Update secret

This commit is contained in:
Vardan Bansal 2023-09-12 19:05:08 -07:00 committed by Dan Wilson
parent 7af506b47e
commit c7390d77b4
5 changed files with 167 additions and 7 deletions

View File

@ -21,7 +21,7 @@ import { useStrings } from 'framework/strings'
import type { OpenapiCreateSecretRequest, TypesSecret } from 'services/code'
import { getErrorMessage } from 'utils/Utils'
interface SecretFormData {
export interface SecretFormData {
value: string
description: string
name: string
@ -82,10 +82,7 @@ export const NewSecretModalButton: React.FC<NewSecretModalButtonProps> = ({
onClose={hideModal}
title={''}
style={{ width: 700, maxHeight: '95vh', overflow: 'auto' }}>
<Layout.Vertical
padding={{ left: 'xxlarge' }}
style={{ height: '100%' }}
data-testid="add-target-to-flag-modal">
<Layout.Vertical padding={{ left: 'xxlarge' }} style={{ height: '100%' }} data-testid="add-secret-modal">
<Heading level={3} font={{ variation: FontVariation.H3 }} margin={{ bottom: 'xlarge' }}>
{modalTitle}
</Heading>

View File

@ -0,0 +1,147 @@
import React, { useState } from 'react'
import * as yup from 'yup'
import { useMutate } from 'restful-react'
import { FontVariation, Intent } from '@harnessio/design-system'
import {
Button,
Dialog,
Layout,
Heading,
Container,
Formik,
FormikForm,
FormInput,
FlexExpander,
useToaster,
StringSubstitute
} from '@harnessio/uicore'
import { Icon } from '@harnessio/icons'
import { useStrings } from 'framework/strings'
import { useModalHook } from 'hooks/useModalHook'
import { useGetSpaceParam } from 'hooks/useGetSpaceParam'
import type { OpenapiUpdateSecretRequest, TypesSecret } from 'services/code'
import type { SecretFormData } from 'components/NewSecretModalButton/NewSecretModalButton'
import { getErrorMessage } from 'utils/Utils'
const useUpdateSecretModal = () => {
const { getString } = useStrings()
const space = useGetSpaceParam()
const { showError, showSuccess } = useToaster()
const [secret, setSecret] = useState<TypesSecret>()
const { mutate: updateSecret, loading } = useMutate<TypesSecret>({
verb: 'PATCH',
path: `/api/v1/secrets/${space}/${secret?.uid}/+`
})
const handleSubmit = async (formData: SecretFormData) => {
try {
const payload: OpenapiUpdateSecretRequest = {
data: formData.value,
description: formData.description,
uid: formData.name
}
await updateSecret(payload)
hideModal()
showSuccess(
<StringSubstitute
str={getString('secrets.secretUpdated')}
vars={{
uid: formData.name
}}
/>
)
} catch (exception) {
showError(getErrorMessage(exception), 0, getString('secrets.failedToUpdateSecret'))
}
}
const [openModal, hideModal] = useModalHook(() => {
const onClose = () => {
hideModal()
}
return (
<Dialog
isOpen
enforceFocus={false}
onClose={hideModal}
title={''}
style={{ width: 700, maxHeight: '95vh', overflow: 'auto' }}>
<Layout.Vertical padding={{ left: 'xxlarge' }} style={{ height: '100%' }} data-testid="add-secret-modal">
<Heading level={3} font={{ variation: FontVariation.H3 }} margin={{ bottom: 'xlarge' }}>
{getString('secrets.updateSecret')}
</Heading>
<Container margin={{ right: 'xxlarge' }}>
<Formik
initialValues={{ name: secret?.uid || '', description: secret?.description || '', value: '' }}
formName="addSecret"
enableReinitialize={true}
validationSchema={yup.object().shape({
name: yup.string().trim().required(),
value: yup.string().trim().required()
})}
validateOnChange
validateOnBlur
onSubmit={handleSubmit}>
<FormikForm>
<FormInput.Text
name="name"
label={getString('name')}
placeholder={getString('secrets.enterSecretName')}
tooltipProps={{
dataTooltipId: 'secretNameTextField'
}}
inputGroup={{ autoFocus: true }}
/>
<FormInput.Text
name="value"
label={getString('value')}
placeholder={getString('secrets.value')}
tooltipProps={{
dataTooltipId: 'secretDescriptionTextField'
}}
inputGroup={{ type: 'password' }}
/>
<FormInput.Text
name="description"
label={getString('description')}
placeholder={getString('enterDescription')}
tooltipProps={{
dataTooltipId: 'secretDescriptionTextField'
}}
isOptional
/>
<Layout.Horizontal
spacing="small"
padding={{ right: 'xxlarge', top: 'xxxlarge', bottom: 'large' }}
style={{ alignItems: 'center' }}>
<Button
type="submit"
text={getString('secrets.updateSecret')}
intent={Intent.PRIMARY}
disabled={loading}
/>
<Button text={getString('cancel')} minimal onClick={onClose} />
<FlexExpander />
{loading && <Icon intent={Intent.PRIMARY} name="steps-spinner" size={16} />}
</Layout.Horizontal>
</FormikForm>
</Formik>
</Container>
</Layout.Vertical>
</Dialog>
)
}, [secret])
return {
openModal: ({ secretToUpdate }: { secretToUpdate: TypesSecret }) => {
setSecret(secretToUpdate)
openModal()
}
}
}
export default useUpdateSecretModal

View File

@ -496,10 +496,13 @@ export interface StringsMap {
'secrets.enterSecretName': string
'secrets.failedToCreate': string
'secrets.failedToDeleteSecret': string
'secrets.failedToUpdateSecret': string
'secrets.name': string
'secrets.newSecretButton': string
'secrets.noData': string
'secrets.secretDeleted': string
'secrets.secretUpdated': string
'secrets.updateSecret': string
'secrets.value': string
selectBranchPlaceHolder: string
selectRange: string
@ -555,6 +558,7 @@ export interface StringsMap {
'unsavedChanges.message': string
'unsavedChanges.stay': string
'unsavedChanges.title': string
update: string
updateFile: string
updateUser: string
updateWebhook: string

View File

@ -137,6 +137,7 @@ createABranch: Create a branch
createATag: Create a tag
delete: Delete
edit: Edit
update: Update
editAsText: Edit as Text
branchName: Branch name
enterBranchPlaceholder: Enter the branch name here
@ -666,9 +667,12 @@ secrets:
createSecret: Create Secret
createSuccess: Secret created successfully
secretDeleted: Secret {uid} deleted.
secretUpdated: Secret {uid} updated.
deleteSecretConfirm: Are you sure you want to delete secret <strong>{{uid}}</strong>? You can't undo this action.
failedToDeleteSecret: Failed to delete Secret. Please try again.
deleteSecret: Delete Secrets
failedToUpdateSecret: Failed to update Secret. Please try again.
deleteSecret: Delete secret
updateSecret: Update secret
userUpdateSuccess: 'User updated successfully'
viewFile: View File
searchResult: 'Search Result {count}'

View File

@ -1,4 +1,4 @@
import React, { useMemo, useState } from 'react'
import React, { useCallback, useMemo, useState } from 'react'
import {
ButtonVariation,
Container,
@ -29,6 +29,7 @@ import { ResourceListingPagination } from 'components/ResourceListingPagination/
import { NewSecretModalButton } from 'components/NewSecretModalButton/NewSecretModalButton'
import { useConfirmAct } from 'hooks/useConfirmAction'
import { OptionsMenuButton } from 'components/OptionsMenuButton/OptionsMenuButton'
import useUpdateSecretModal from 'components/UpdateSecretModal/UpdateSecretModal'
import noSecretsImage from '../RepositoriesListing/no-repo.svg'
import css from './SecretList.module.scss'
@ -61,6 +62,8 @@ const SecretList = () => {
onSuccess={() => refetch()}></NewSecretModalButton>
)
const { openModal: openUpdateSecretModal } = useUpdateSecretModal()
const columns: Column<TypesSecret>[] = useMemo(
() => [
{
@ -113,6 +116,11 @@ const SecretList = () => {
isDark
width="100px"
items={[
{
text: getString('edit'),
isDanger: true,
onClick: () => openUpdateSecretModal({ secretToUpdate: row.original })
},
{
text: getString('delete'),
isDanger: true,