diff --git a/site/src/i18n/en/tokensPage.json b/site/src/i18n/en/tokensPage.json
index 4a2eaa2fe5ce2..d1bd9c4ca083a 100644
--- a/site/src/i18n/en/tokensPage.json
+++ b/site/src/i18n/en/tokensPage.json
@@ -6,7 +6,7 @@
"addToken": "Add token",
"deleteToken": {
"delete": "Delete Token",
- "deleteCaption": "Are you sure you want to delete this token?
<4>{{tokenId}}4>",
+ "deleteCaption": "Are you sure you want to permanently delete token <4>{{tokenName}}4>?",
"deleteSuccess": "Token has been deleted",
"deleteFailure": "Failed to delete token"
}
diff --git a/site/src/pages/UserSettingsPage/TokensPage/TokensPage.tsx b/site/src/pages/UserSettingsPage/TokensPage/TokensPage.tsx
index d1d0c2e61648f..af4d569824b29 100644
--- a/site/src/pages/UserSettingsPage/TokensPage/TokensPage.tsx
+++ b/site/src/pages/UserSettingsPage/TokensPage/TokensPage.tsx
@@ -9,6 +9,7 @@ import { Stack } from "components/Stack/Stack"
import Button from "@material-ui/core/Button"
import { Link as RouterLink } from "react-router-dom"
import AddIcon from "@material-ui/icons/AddOutlined"
+import { APIKeyWithOwner } from "api/typesGenerated"
export const TokensPage: FC> = () => {
const styles = useStyles()
@@ -30,9 +31,9 @@ export const TokensPage: FC> = () => {
)
- const [tokenIdToDelete, setTokenIdToDelete] = useState(
- undefined,
- )
+ const [tokenToDelete, setTokenToDelete] = useState<
+ APIKeyWithOwner | undefined
+ >(undefined)
const {
data: tokens,
@@ -60,15 +61,15 @@ export const TokensPage: FC> = () => {
isLoading={isFetching}
hasLoaded={isFetched}
getTokensError={getTokensError}
- onDelete={(id) => {
- setTokenIdToDelete(id)
+ onDelete={(token) => {
+ setTokenToDelete(token)
}}
/>
>
)
diff --git a/site/src/pages/UserSettingsPage/TokensPage/TokensPageView.tsx b/site/src/pages/UserSettingsPage/TokensPage/TokensPageView.tsx
index f62c70f6e6a23..71d9449371327 100644
--- a/site/src/pages/UserSettingsPage/TokensPage/TokensPageView.tsx
+++ b/site/src/pages/UserSettingsPage/TokensPage/TokensPageView.tsx
@@ -28,7 +28,7 @@ export interface TokensPageViewProps {
getTokensError?: Error | unknown
isLoading: boolean
hasLoaded: boolean
- onDelete: (id: string) => void
+ onDelete: (token: APIKeyWithOwner) => void
deleteTokenError?: Error | unknown
}
@@ -114,7 +114,7 @@ export const TokensPageView: FC<
{
- onDelete(token.id)
+ onDelete(token)
}}
size="medium"
aria-label={t("tokenActions.deleteToken.delete")}
diff --git a/site/src/pages/UserSettingsPage/TokensPage/components/ConfirmDeleteDialog.stories.tsx b/site/src/pages/UserSettingsPage/TokensPage/components/ConfirmDeleteDialog.stories.tsx
new file mode 100644
index 0000000000000..6f254680dc167
--- /dev/null
+++ b/site/src/pages/UserSettingsPage/TokensPage/components/ConfirmDeleteDialog.stories.tsx
@@ -0,0 +1,39 @@
+import { Story } from "@storybook/react"
+import { MockToken } from "testHelpers/entities"
+import {
+ ConfirmDeleteDialog,
+ ConfirmDeleteDialogProps,
+} from "./ConfirmDeleteDialog"
+import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
+
+const queryClient = new QueryClient({
+ defaultOptions: {
+ queries: {
+ retry: false,
+ cacheTime: 0,
+ refetchOnWindowFocus: false,
+ },
+ },
+})
+
+export default {
+ title: "components/ConfirmDeleteDialog",
+ component: ConfirmDeleteDialog,
+}
+
+const Template: Story = (
+ args: ConfirmDeleteDialogProps,
+) => (
+
+
+
+)
+
+export const DeleteDialog = Template.bind({})
+DeleteDialog.args = {
+ queryKey: ["tokens"],
+ token: MockToken,
+ setToken: () => {
+ return null
+ },
+}
diff --git a/site/src/pages/UserSettingsPage/TokensPage/components/ConfirmDeleteDialog.tsx b/site/src/pages/UserSettingsPage/TokensPage/components/ConfirmDeleteDialog.tsx
index 166836c31668e..90d2477843be5 100644
--- a/site/src/pages/UserSettingsPage/TokensPage/components/ConfirmDeleteDialog.tsx
+++ b/site/src/pages/UserSettingsPage/TokensPage/components/ConfirmDeleteDialog.tsx
@@ -4,24 +4,28 @@ import { useTranslation, Trans } from "react-i18next"
import { useDeleteToken } from "../hooks"
import { displaySuccess, displayError } from "components/GlobalSnackbar/utils"
import { getErrorMessage } from "api/errors"
+import { APIKeyWithOwner } from "api/typesGenerated"
-export const ConfirmDeleteDialog: FC<{
+export interface ConfirmDeleteDialogProps {
queryKey: (string | boolean)[]
- tokenId: string | undefined
- setTokenId: (arg: string | undefined) => void
-}> = ({ queryKey, tokenId, setTokenId }) => {
- const { t } = useTranslation("tokensPage")
+ token: APIKeyWithOwner | undefined
+ setToken: (arg: APIKeyWithOwner | undefined) => void
+}
+export const ConfirmDeleteDialog: FC = ({
+ queryKey,
+ token,
+ setToken,
+}) => {
+ const { t } = useTranslation("tokensPage")
+ const tokenName = token?.token_name
const description = (
- Are you sure you want to delete this token?
-
-
- {{ tokenId }}
+ Are you sure you want to permanently delete token {{ tokenName }}?
)
@@ -30,7 +34,7 @@ export const ConfirmDeleteDialog: FC<{
const onDeleteSuccess = () => {
displaySuccess(t("tokenActions.deleteToken.deleteSuccess"))
- setTokenId(undefined)
+ setToken(undefined)
}
const onDeleteError = (error: unknown) => {
@@ -39,26 +43,27 @@ export const ConfirmDeleteDialog: FC<{
t("tokenActions.deleteToken.deleteFailure"),
)
displayError(message)
- setTokenId(undefined)
+ setToken(undefined)
}
return (
{
- if (!tokenId) {
+ if (!token) {
return
}
- deleteToken(tokenId, {
+ deleteToken(token.id, {
onError: onDeleteError,
onSuccess: onDeleteSuccess,
})
}}
onClose={() => {
- setTokenId(undefined)
+ setToken(undefined)
}}
/>
)
diff --git a/site/src/testHelpers/entities.ts b/site/src/testHelpers/entities.ts
index 01a2ab60cc090..478e841ddd29b 100644
--- a/site/src/testHelpers/entities.ts
+++ b/site/src/testHelpers/entities.ts
@@ -37,19 +37,22 @@ export const MockAPIKey: TypesGen.GenerateAPIKeyResponse = {
key: "my-api-key",
}
-export const MockTokens: TypesGen.APIKey[] = [
- {
- id: "tBoVE3dqLl",
- user_id: "f9ee61d8-1d84-4410-ab6e-c1ec1a641e0b",
- last_used: "0001-01-01T00:00:00Z",
- expires_at: "2023-01-15T20:10:45.637438Z",
- created_at: "2022-12-16T20:10:45.637452Z",
- updated_at: "2022-12-16T20:10:45.637452Z",
- login_type: "token",
- scope: "all",
- lifetime_seconds: 2592000,
- token_name: "token-one",
- },
+export const MockToken: TypesGen.APIKeyWithOwner = {
+ id: "tBoVE3dqLl",
+ user_id: "f9ee61d8-1d84-4410-ab6e-c1ec1a641e0b",
+ last_used: "0001-01-01T00:00:00Z",
+ expires_at: "2023-01-15T20:10:45.637438Z",
+ created_at: "2022-12-16T20:10:45.637452Z",
+ updated_at: "2022-12-16T20:10:45.637452Z",
+ login_type: "token",
+ scope: "all",
+ lifetime_seconds: 2592000,
+ token_name: "token-one",
+ username: "admin",
+}
+
+export const MockTokens: TypesGen.APIKeyWithOwner[] = [
+ MockToken,
{
id: "tBoVE3dqLl",
user_id: "f9ee61d8-1d84-4410-ab6e-c1ec1a641e0b",
@@ -61,6 +64,7 @@ export const MockTokens: TypesGen.APIKey[] = [
scope: "all",
lifetime_seconds: 2592000,
token_name: "token-two",
+ username: "admin",
},
]