From 9104e470790abf85563bb86b56da66dcb5c0ffbc Mon Sep 17 00:00:00 2001 From: Drake Costa Date: Mon, 21 Jul 2025 04:07:17 -0700 Subject: [PATCH] Move `EditSecretModal` to be child of `SecretRow` In the accompanying PR for `DeleteSecretModal`, that one will also be moved over to `SecretRow` --- .../Vault/Secrets/EditSecretModal.tsx | 36 +++++----- .../Integrations/Vault/Secrets/SecretRow.tsx | 66 ++++++++++--------- .../Vault/Secrets/SecretsManagement.tsx | 52 ++++++++------- .../__tests__/EditSecretModal.test.tsx | 2 +- 4 files changed, 81 insertions(+), 75 deletions(-) diff --git a/apps/studio/components/interfaces/Integrations/Vault/Secrets/EditSecretModal.tsx b/apps/studio/components/interfaces/Integrations/Vault/Secrets/EditSecretModal.tsx index 25f713ac250..92b4aae22d4 100644 --- a/apps/studio/components/interfaces/Integrations/Vault/Secrets/EditSecretModal.tsx +++ b/apps/studio/components/interfaces/Integrations/Vault/Secrets/EditSecretModal.tsx @@ -27,7 +27,7 @@ import { EyeOff, Eye } from 'lucide-react' import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout' interface EditSecretModalProps { - selectedSecret: VaultSecret | undefined + secret: VaultSecret | undefined onClose: () => void } @@ -37,39 +37,39 @@ const SecretSchema = z.object({ secret: z.string().min(1, 'Please enter your secret value'), }) -const EditSecretModal = ({ selectedSecret, onClose }: EditSecretModalProps) => { +const EditSecretModal = ({ secret, onClose }: EditSecretModalProps) => { const [showSecretValue, setShowSecretValue] = useState(false) const { project } = useProjectContext() const formId = 'edit-vault-secret-form' const { data, isLoading: isLoadingSecretValue } = useVaultSecretDecryptedValueQuery( { projectRef: project?.ref!, - id: selectedSecret?.id!, + id: secret?.id!, connectionString: project?.connectionString, }, - { enabled: selectedSecret !== undefined && !!(project?.ref && selectedSecret?.id) } + { enabled: secret !== undefined && !!(project?.ref && secret?.id) } ) const form = useForm>({ resolver: zodResolver(SecretSchema), defaultValues: { - name: selectedSecret?.name ?? '', - description: selectedSecret?.description ?? '', - secret: selectedSecret?.decryptedSecret ?? data ?? '', + name: secret?.name ?? '', + description: secret?.description ?? '', + secret: secret?.decryptedSecret ?? data ?? '', }, values: { - name: selectedSecret?.name ?? '', - description: selectedSecret?.description ?? '', - secret: selectedSecret?.decryptedSecret ?? data ?? '', + name: secret?.name ?? '', + description: secret?.description ?? '', + secret: secret?.decryptedSecret ?? data ?? '', }, }) useEffect(() => { - if (selectedSecret !== undefined) { + if (secret !== undefined) { setShowSecretValue(false) } - }, [selectedSecret]) + }, [secret]) - const { mutateAsync: updateSecret, isLoading: isSubmitting } = useVaultSecretUpdateMutation() + const { mutate: updateSecret, isLoading: isSubmitting } = useVaultSecretUpdateMutation() const onSubmit: SubmitHandler> = async (values) => { if (!project) return console.error('Project is required') @@ -77,15 +77,15 @@ const EditSecretModal = ({ selectedSecret, onClose }: EditSecretModalProps) => { const payload: Partial = { secret: values.secret, } - if (values.name !== selectedSecret?.name) payload.name = values.name - if (values.description !== selectedSecret?.description) payload.description = values.description + if (values.name !== secret?.name) payload.name = values.name + if (values.description !== secret?.description) payload.description = values.description - if (!isEmpty(payload) && selectedSecret) { + if (!isEmpty(payload) && secret) { updateSecret( { projectRef: project.ref, connectionString: project?.connectionString, - id: selectedSecret.id, + id: secret.id, ...payload, }, { @@ -103,7 +103,7 @@ const EditSecretModal = ({ selectedSecret, onClose }: EditSecretModalProps) => { return ( { if (!open) { form.reset() diff --git a/apps/studio/components/interfaces/Integrations/Vault/Secrets/SecretRow.tsx b/apps/studio/components/interfaces/Integrations/Vault/Secrets/SecretRow.tsx index 0a79deb18af..e9e9fa1cc8f 100644 --- a/apps/studio/components/interfaces/Integrations/Vault/Secrets/SecretRow.tsx +++ b/apps/studio/components/interfaces/Integrations/Vault/Secrets/SecretRow.tsx @@ -20,17 +20,17 @@ import { useVaultSecretDecryptedValueQuery } from 'data/vault/vault-secret-decry import { useCheckPermissions } from 'hooks/misc/useCheckPermissions' import { Edit3, Eye, EyeOff, Key, Loader, MoreVertical, Trash } from 'lucide-react' import type { VaultSecret } from 'types' +import EditSecretModal from './EditSecretModal' interface SecretRowProps { secret: VaultSecret - onSelectEdit: (secret: VaultSecret) => void onSelectRemove: (secret: VaultSecret) => void } const SecretRow = ({ secret, onSelectEdit, onSelectRemove }: SecretRowProps) => { const { ref } = useParams() const { project } = useProjectContext() - + const [modal, setModal] = useState(null) const [revealSecret, setRevealSecret] = useState(false) const name = secret?.name ?? 'No name provided' @@ -46,6 +46,15 @@ const SecretRow = ({ secret, onSelectEdit, onSelectRemove }: SecretRowProps) => enabled: !!(ref! && secret.id) && revealSecret, } ) + const renderModal = () => { + const onClose = () => setModal(null) + switch (modal) { + case `edit`: + return + default: + return null + } + } return (
@@ -95,31 +104,25 @@ const SecretRow = ({ secret, onSelectEdit, onSelectRemove }: SecretRowProps) => {secret.updated_at === secret.created_at ? 'Added' : 'Updated'} on{' '} {dayjs(secret.updated_at).format('MMM D, YYYY')}

- - -
) diff --git a/apps/studio/components/interfaces/Integrations/Vault/Secrets/SecretsManagement.tsx b/apps/studio/components/interfaces/Integrations/Vault/Secrets/SecretsManagement.tsx index 47a7262ee50..7282523ab6e 100644 --- a/apps/studio/components/interfaces/Integrations/Vault/Secrets/SecretsManagement.tsx +++ b/apps/studio/components/interfaces/Integrations/Vault/Secrets/SecretsManagement.tsx @@ -9,22 +9,29 @@ import { ButtonTooltip } from 'components/ui/ButtonTooltip' import { DocsButton } from 'components/ui/DocsButton' import { useVaultSecretsQuery } from 'data/vault/vault-secrets-query' import { useCheckPermissions } from 'hooks/misc/useCheckPermissions' -import type { VaultSecret } from 'types' -import { Button, Input, Listbox, Separator } from 'ui' +import { + Button, + Input, + Select_Shadcn_, + SelectContent_Shadcn_, + SelectItem_Shadcn_, + SelectTrigger_Shadcn_, + SelectValue_Shadcn_, + Separator, +} from 'ui' import AddNewSecretModal from './AddNewSecretModal' import DeleteSecretModal from './DeleteSecretModal' -import EditSecretModal from './EditSecretModal' import SecretRow from './SecretRow' +import { VaultSecret } from 'types' export const SecretsManagement = () => { const { search } = useParams() const { project } = useProjectContext() const [searchValue, setSearchValue] = useState('') - const [selectedSort, setSelectedSort] = useState<'updated_at' | 'name'>('updated_at') const [showAddSecretModal, setShowAddSecretModal] = useState(false) - const [selectedSecretToEdit, setSelectedSecretToEdit] = useState() const [selectedSecretToRemove, setSelectedSecretToRemove] = useState() + const [selectedSort, setSelectedSort] = useState('updated_at') const canManageSecrets = useCheckPermissions(PermissionAction.TENANT_SQL_ADMIN_WRITE, 'tables') @@ -49,7 +56,7 @@ export const SecretsManagement = () => { if (selectedSort === 'updated_at') { return Number(new Date(s.updated_at)) } else { - return s[selectedSort] + return s[selectedSort as keyof VaultSecret] } } ) @@ -81,26 +88,26 @@ export const SecretsManagement = () => { : [] } /> -
- - + + + + <>Sort by {selectedSort} + + + + Updated at - - + id="name" className="max-w-[180px]" value="name" label="Sort by name" > Name - - -
+ + +
@@ -136,7 +143,6 @@ export const SecretsManagement = () => { {idx !== secrets.length - 1 && } @@ -167,12 +173,8 @@ export const SecretsManagement = () => {
- setSelectedSecretToEdit(undefined)} - /> setSelectedSecretToRemove(undefined)} /> void }) => { { setSelectedSecretToEdit(undefined) onClose()