From f93058ca73ec8d0862b0f1ea329ab469b0866468 Mon Sep 17 00:00:00 2001 From: Joshen Lim Date: Mon, 14 Jul 2025 21:51:31 +0800 Subject: [PATCH] Improve loading and success handlers for JWT keys (#37109) --- .../jwt-secret-keys-table/index.tsx | 44 ++++++++++++++----- .../jwt-secret-keys-table/signing-key-row.tsx | 44 ++++++++++++++----- 2 files changed, 66 insertions(+), 22 deletions(-) diff --git a/apps/studio/components/interfaces/JwtSecrets/jwt-secret-keys-table/index.tsx b/apps/studio/components/interfaces/JwtSecrets/jwt-secret-keys-table/index.tsx index 51eb792891c..52227d9be6a 100644 --- a/apps/studio/components/interfaces/JwtSecrets/jwt-secret-keys-table/index.tsx +++ b/apps/studio/components/interfaces/JwtSecrets/jwt-secret-keys-table/index.tsx @@ -55,6 +55,7 @@ export default function JWTSecretKeysTable() { const newJwtSecrets = useFlag('newJwtSecrets') const [selectedKey, setSelectedKey] = useState() + const [selectedKeyToUpdate, setSelectedKeyToUpdate] = useState() const [shownDialog, setShownDialog] = useState() const { data: signingKeys, isLoading: isLoadingSigningKeys } = useJWTSigningKeysQuery({ @@ -76,7 +77,12 @@ export default function JWTSecretKeysTable() { ) const { mutate: updateJWTSigningKey, isLoading: isUpdatingJWTSigningKey } = - useJWTSigningKeyUpdateMutation({ onSuccess: () => resetDialog() }) + useJWTSigningKeyUpdateMutation({ + onSuccess: () => { + resetDialog() + setSelectedKeyToUpdate(undefined) + }, + }) const { mutate: deleteJWTSigningKey, isLoading: isDeletingJWTSigningKey } = useJWTSigningKeyDeleteMutation({ onSuccess: () => resetDialog(), onError: () => resetDialog() }) @@ -118,19 +124,33 @@ export default function JWTSecretKeysTable() { } const handlePreviouslyUsedKey = async (keyId: string) => { - updateJWTSigningKey({ projectRef, keyId, status: 'previously_used' }) + setSelectedKeyToUpdate(keyId) + updateJWTSigningKey( + { projectRef, keyId, status: 'previously_used' }, + { onSuccess: () => toast.success('Successfully moved key to previously used') } + ) } const handleStandbyKey = (keyId: string) => { - updateJWTSigningKey({ projectRef: projectRef!, keyId, status: 'standby' }) + setSelectedKeyToUpdate(keyId) + updateJWTSigningKey( + { projectRef: projectRef!, keyId, status: 'standby' }, + { onSuccess: () => toast.success('Successfully moved key to standby') } + ) } const handleRevokeKey = (keyId: string) => { - updateJWTSigningKey({ projectRef: projectRef!, keyId, status: 'revoked' }) + updateJWTSigningKey( + { projectRef: projectRef!, keyId, status: 'revoked' }, + { onSuccess: () => toast.success('Successfully revoked key') } + ) } const handleDeleteKey = (keyId: string) => { - deleteJWTSigningKey({ projectRef: projectRef!, keyId }) + deleteJWTSigningKey( + { projectRef: projectRef!, keyId }, + { onSuccess: () => toast.success('Successfully deleted key') } + ) } if (isLoading) { @@ -152,7 +172,7 @@ export default function JWTSecretKeysTable() { description="Switch the standby key to in use. All new JSON Web Tokens issued by Supabase Auth will be signed with this key." buttonLabel="Rotate keys" onClick={() => setShownDialog('rotate')} - loading={isLoadingMutation} + loading={isUpdatingJWTSigningKey} icon={} type="primary" /> @@ -206,12 +226,15 @@ export default function JWTSecretKeysTable() { )} {inUseKey && ( @@ -271,12 +294,13 @@ export default function JWTSecretKeysTable() { ))} diff --git a/apps/studio/components/interfaces/JwtSecrets/jwt-secret-keys-table/signing-key-row.tsx b/apps/studio/components/interfaces/JwtSecrets/jwt-secret-keys-table/signing-key-row.tsx index 15ea69469ce..cbb86d1f7f0 100644 --- a/apps/studio/components/interfaces/JwtSecrets/jwt-secret-keys-table/signing-key-row.tsx +++ b/apps/studio/components/interfaces/JwtSecrets/jwt-secret-keys-table/signing-key-row.tsx @@ -12,6 +12,7 @@ import { } from 'lucide-react' import { components } from 'api-types' +import { DropdownMenuItemTooltip } from 'components/ui/DropdownMenuItemTooltip' import { JWTSigningKey } from 'data/jwt-signing-keys/jwt-signing-keys-query' import { Badge, @@ -35,6 +36,7 @@ interface SigningKeyRowProps { handleStandbyKey: (keyId: string) => void legacyKey?: JWTSigningKey | null standbyKey?: JWTSigningKey | null + isLoading?: boolean } const MotionTableRow = motion(TableRow) @@ -47,6 +49,7 @@ export const SigningKeyRow = ({ handleStandbyKey, legacyKey, standbyKey, + isLoading = false, }: SigningKeyRowProps) => ( -