Skip to content
Snippets Groups Projects
Commit be9193fa authored by brunoravera's avatar brunoravera
Browse files

edit implementation

parent cf9a7847
No related branches found
No related tags found
No related merge requests found
......@@ -15,3 +15,10 @@ export interface CreateImplementationRequest {
description: string
dockerhubImageName: string
}
export interface UpdateImplementationRequest {
id: Implementation['id']
name: string
description: string
dockerhubImageName: string
}
......@@ -125,7 +125,7 @@ const ActionsRow: React.FC<ActionsRowProps> = ({ pattern }) => {
icon={<Icon as={FaPlus} />}
/>
</AddImplementationButton>
<Tooltip label={<Text>Editar patron</Text>}>
<Tooltip label={<Text>Editar</Text>}>
<IconButton
aria-label="edit pattern"
variant="unstyled"
......
import {
Modal,
ModalContent,
ModalHeader,
ModalOverlay,
ModalProps,
useDisclosure,
Text,
ModalCloseButton,
ModalBody,
VStack,
FormControl,
FormLabel,
HStack,
FormErrorMessage,
Input,
Tooltip,
Icon,
Textarea,
ModalFooter,
Button,
} from '@chakra-ui/react'
import { useFormik } from 'formik'
import React from 'react'
import { Implementation } from 'src/models'
import { EditImplementationSchema, editImplementationSchema } from './schema'
import { FaInfo } from 'react-icons/fa'
import { UpdateImplementationMutation } from '../query-builder/update-implementation-mutation'
import { useQueryClient } from 'react-query'
import { GetImplementationQuery } from '../query-builder/get-implementation-query'
import { GetImplementationsByPatternIdQuery } from '../query-builder/get-implementations-by-pattern-id-query'
const FORM_ID = 'edit-implementation-form'
export type EditImplementationModalProps = {
disclosure: ReturnType<typeof useDisclosure>
implementation: Implementation
patternId: string
} & Partial<ModalProps>
export const EditImplementationModal: React.FC<
EditImplementationModalProps
> = ({ disclosure, implementation, patternId, ...props }) => {
const queryClient = useQueryClient()
const updateImplementationMutation =
UpdateImplementationMutation.useMutation()
const handleOnSubmit = async (values: EditImplementationSchema) => {
await updateImplementationMutation.mutateAsync({
id: implementation.id,
name: values.name,
dockerhubImageName: values.dockerhubImageName,
description: values.description,
})
queryClient.invalidateQueries(
GetImplementationQuery.getKey({ id: implementation.id })
)
queryClient.invalidateQueries(
GetImplementationsByPatternIdQuery.getKey({
patternId: patternId,
})
)
disclosure.onClose()
}
const {
handleSubmit,
handleReset,
handleChange,
setTouched,
values,
isSubmitting,
errors,
touched,
isValid,
} = useFormik({
enableReinitialize: true,
initialValues: {
name: implementation.name,
description: implementation.description,
dockerhubImageName: implementation.dockerhubImageName,
},
validateOnBlur: true,
validateOnChange: true,
validateOnMount: true,
validationSchema: editImplementationSchema,
onSubmit: handleOnSubmit,
})
return (
<>
{disclosure.isOpen && (
<Modal size="xl" {...disclosure} {...props}>
<ModalOverlay />
<ModalContent>
<ModalHeader>
<Text fontSize="md">
Editar implementacion {implementation.name}
</Text>
</ModalHeader>
<ModalCloseButton mt="-2" mr="-2" />
<form id={FORM_ID} onSubmit={handleSubmit} onReset={handleReset}>
<ModalBody>
<VStack>
<FormControl isInvalid={Boolean(errors.name) && touched.name}>
<FormLabel>
<HStack>
<Text fontSize="sm">Nombre</Text>
<Text color="red">*</Text>
</HStack>
</FormLabel>
<Input
name="name"
autoFocus
value={values.name}
onChange={(e) => {
setTouched({ ...touched, name: true })
handleChange(e)
}}
/>
<FormErrorMessage>{errors.name}</FormErrorMessage>
</FormControl>
<FormControl
isInvalid={
Boolean(errors.dockerhubImageName) &&
touched.dockerhubImageName
}
>
<FormLabel>
<HStack>
<Text fontSize="sm">
Nombre de la imagen en Dockerhub
</Text>
<Text color="red">*</Text>
<Tooltip
label="Nombre de la imagen en Dockerhub con la implementacion"
shouldWrapChildren
hasArrow
>
<Icon as={FaInfo} color="blue.500" />
</Tooltip>
</HStack>
</FormLabel>
<Input
name="dockerhubImageName"
autoFocus
value={values.dockerhubImageName}
onChange={(e) => {
setTouched({ ...touched, dockerhubImageName: true })
handleChange(e)
}}
/>
<FormErrorMessage>
{errors.dockerhubImageName}
</FormErrorMessage>
</FormControl>
<FormControl
isInvalid={
Boolean(errors.description) && touched.description
}
>
<FormLabel>
<HStack>
<Text fontSize="sm">Descripcion</Text>
<Text color="red">*</Text>
</HStack>
</FormLabel>
<Textarea
name="description"
value={values.description}
onChange={(e) => {
setTouched({ ...touched, description: true })
handleChange(e)
}}
/>
<FormErrorMessage>{errors.description}</FormErrorMessage>
</FormControl>
</VStack>
</ModalBody>
</form>
<ModalFooter>
<HStack>
<Button variant="outline" onClick={disclosure.onClose}>
Cancelar
</Button>
<Button
form={FORM_ID}
variant="solid"
colorScheme="blue"
type="submit"
isLoading={isSubmitting}
isDisabled={!isValid}
>
Guardar
</Button>
</HStack>
</ModalFooter>
</ModalContent>
</Modal>
)}
</>
)
}
export * from './edit-implementation-modal'
import * as yup from 'yup'
import { Implementation } from 'src/models'
export type EditImplementationSchema = Pick<
Implementation,
'name' | 'description' | 'dockerhubImageName'
>
const IMPLEMENTATION_NAME_MAX_LENGHT = 255
const IMPLEMENTATION_DOCKERHUB_IMAGE_NAME_MAX_LENGHT = 255
export const editImplementationSchema = yup
.object()
.shape<EditImplementationSchema>({
name: yup
.string()
.max(
IMPLEMENTATION_NAME_MAX_LENGHT,
`El nombre debe tener menos de ${IMPLEMENTATION_NAME_MAX_LENGHT} caracteres`
)
.required('El nombre es requerido'),
dockerhubImageName: yup
.string()
.max(
IMPLEMENTATION_DOCKERHUB_IMAGE_NAME_MAX_LENGHT,
`El nombre de la imagen de docker debe tener menos de ${IMPLEMENTATION_DOCKERHUB_IMAGE_NAME_MAX_LENGHT} caracteres`
)
.required('El nombre de la implementacion en dockerhub es requerido'),
description: yup.string().required('La descripcion es requerida'),
})
......@@ -18,7 +18,7 @@ import {
Button,
useDisclosure,
} from '@chakra-ui/react'
import { FaEye, FaPlay, FaPlus, FaTrash, FaVial, FaVials } from 'react-icons/fa'
import { FaEdit, FaPlay, FaTrash, FaVial } from 'react-icons/fa'
import { Implementation, Pattern } from 'src/models'
import { GetPatternQuery } from '../patterns/query-builder'
......@@ -29,6 +29,7 @@ import { RunTestsButton } from './run-tests'
import { DeleteImplementationMutation } from './query-builder/delete-implementation-mutation'
import { useQueryClient } from 'react-query'
import { navigate, routes } from '@redwoodjs/router'
import { EditImplementationModal } from './edit-implementation'
const tableHeaders = [
'Nombre',
......@@ -140,42 +141,58 @@ const ActionsRow: React.FC<ActionsRowProps> = ({
handleOnDeleteImplementation,
handleOnViewReport,
}) => {
const editImplementationDisclosure = useDisclosure()
return (
<HStack>
<Tooltip shouldWrapChildren hasArrow label={<Text>Ver detalles</Text>}>
<IconButton
aria-label="view implementation"
variant="unstyled"
icon={<Icon as={FaEye} />}
/>
</Tooltip>
<RunTestsButton implementation={implementation} pattern={pattern}>
<IconButton
aria-label="test implementation"
variant="unstyled"
icon={<Icon as={FaPlay} />}
/>
</RunTestsButton>
<Tooltip
shouldWrapChildren
hasArrow
label={<Text>Eliminar implementacion</Text>}
>
<IconButton
onClick={() => handleOnDeleteImplementation(implementation.id)}
aria-label="delete implementation"
variant="unstyled"
icon={<Icon as={FaTrash} />}
/>
</Tooltip>
<Tooltip shouldWrapChildren hasArrow label={<Text>Ver reportes</Text>}>
<IconButton
onClick={() => handleOnViewReport(implementation.id)}
aria-label="view reports"
variant="unstyled"
icon={<Icon as={FaVial} />}
<>
<HStack>
<Tooltip shouldWrapChildren hasArrow label={<Text>Editar</Text>}>
<IconButton
aria-label="edit implementation"
variant="unstyled"
onClick={() => editImplementationDisclosure.onOpen()}
icon={<Icon as={FaEdit} />}
/>
</Tooltip>
<RunTestsButton
implementation={implementation}
pattern={pattern}
hasTooltip
>
<IconButton
aria-label="test implementation"
variant="unstyled"
icon={<Icon as={FaPlay} />}
/>
</RunTestsButton>
<Tooltip
shouldWrapChildren
hasArrow
label={<Text>Eliminar implementacion</Text>}
>
<IconButton
onClick={() => handleOnDeleteImplementation(implementation.id)}
aria-label="delete implementation"
variant="unstyled"
icon={<Icon as={FaTrash} />}
/>
</Tooltip>
<Tooltip shouldWrapChildren hasArrow label={<Text>Ver reportes</Text>}>
<IconButton
onClick={() => handleOnViewReport(implementation.id)}
aria-label="view reports"
variant="unstyled"
icon={<Icon as={FaVial} />}
/>
</Tooltip>
</HStack>
{editImplementationDisclosure.isOpen && (
<EditImplementationModal
disclosure={editImplementationDisclosure}
implementation={implementation}
patternId={pattern.id}
/>
</Tooltip>
</HStack>
)}
</>
)
}
import { AxiosError } from 'axios'
import { useMutation as useRQMutation, UseMutationOptions } from 'react-query'
import { Implementation, UpdateImplementationRequest } from 'src/models'
import axiosService from 'src/services/axios-service'
export namespace UpdateImplementationMutation {
export type Params = UpdateImplementationRequest
export type Response = Implementation
export const key = ['update', 'implementation']
export const mutationFn = (params: Params) =>
axiosService
.put<Response>(`/implementations/${params.id}`, params)
.then((res) => res.data)
export const useMutation = (
options: UseMutationOptions<
Response,
AxiosError,
UpdateImplementationRequest
> = {}
) => {
return useRQMutation(mutationFn, { ...options, mutationKey: key })
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment