1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-22 18:50:08 +03:00

F #5422: Fix dev api component (#1598)

(cherry picked from commit 4eb9d5926f20266acdda62d1eda6818b16a91aea)
This commit is contained in:
Sergio Betanzos 2021-11-22 11:20:26 +01:00 committed by Tino Vazquez
parent b89079d865
commit 08176d4f8e
No known key found for this signature in database
GPG Key ID: 14201E424D02047E
4 changed files with 142 additions and 77 deletions

View File

@ -35,14 +35,14 @@ const ResponseForm = ({
handleChangeResponse,
command: { name, httpMethod, params }
}) => {
const { control, handleSubmit, errors, formState } = useForm()
const { control, handleSubmit, formState } = useForm()
const memoParams = useMemo(() => Object.entries(params), [name])
const onSubmit = async dataForm => {
try {
const config = requestConfig(dataForm, { name, httpMethod, params })
const { id, ...res } = await RestClient.request(config) ?? {}
const res = await RestClient.request(config) ?? {}
handleChangeResponse(JSON.stringify(res, null, '\t'))
} catch (err) {
handleChangeResponse(JSON.stringify(err.data, null, '\t'))
@ -68,66 +68,70 @@ const ResponseForm = ({
onSubmit={handleSubmit(onSubmit)}
autoComplete='off'
>
{memoParams?.map(([nameParam, { default: defaultValue }]) => (
<Grid item xs={12} key={`param-${nameParam}`}>
<Controller
render={({ value, onChange, ...controllerProps }) => ({
boolean: <FormControlLabel
control={(
<Checkbox
color='primary'
onChange={e => onChange(e.target.checked)}
/>
)}
label={nameParam}
labelPlacement='end'
/>,
object: <Autocomplete
fullWidth
multiple
color='secondary'
freeSolo
options={[]}
onChange={(_, newValue) => onChange(newValue ?? '')}
renderTags={(tags, getTagProps) =>
tags.map((tag, index) => (
<Chip
key={`${index}-${tag}`}
variant='outlined'
label={tag}
{...getTagProps({ index })}
{memoParams?.map(([paramName, { default: defaultValue }]) => {
const { message: errorMessage } = formState.errors[paramName] ?? {}
return (
<Grid item xs={12} key={`param-${paramName}`}>
<Controller
render={({ value, onChange, ...controllerProps }) => ({
boolean: <FormControlLabel
control={(
<Checkbox
color='primary'
onChange={e => onChange(e.target.checked)}
/>
))
}
renderInput={(params) => (
<TextField
{...params}
fullWidth
label={nameParam}
color='secondary'
error={Boolean(errors[name])}
helperText={errors[name]?.message}
/>
)}
/>
}[typeof defaultValue] ?? (
<TextField
error={Boolean(errors[name])}
helperText={errors[name]?.message}
fullWidth
value={value ?? ''}
label={nameParam}
color='secondary'
onChange={onChange}
{...controllerProps}
/>
))}
control={control}
name={`${nameParam}`}
defaultValue={defaultValue}
/>
</Grid>
))}
)}
label={paramName}
labelPlacement='end'
/>,
object: <Autocomplete
fullWidth
multiple
color='secondary'
freeSolo
options={[]}
onChange={(_, newValue) => onChange(newValue ?? '')}
renderTags={(tags, getTagProps) =>
tags.map((tag, index) => (
<Chip
key={`${index}-${tag}`}
variant='outlined'
label={tag}
{...getTagProps({ index })}
/>
))
}
renderInput={(params) => (
<TextField
{...params}
fullWidth
label={paramName}
color='secondary'
error={Boolean(errorMessage)}
helperText={errorMessage}
/>
)}
/>
}[typeof defaultValue] ?? (
<TextField
error={Boolean(errorMessage)}
helperText={errorMessage}
fullWidth
value={value ?? ''}
label={paramName}
color='secondary'
onChange={onChange}
{...controllerProps}
/>
))}
control={control}
name={`${paramName}`}
defaultValue={defaultValue}
/>
</Grid>
)
})}
<Grid item xs={12}>
<SubmitButton
color='secondary'

View File

@ -14,7 +14,7 @@
* limitations under the License. *
* ------------------------------------------------------------------------- */
import { useState, useMemo, JSXElementConstructor } from 'react'
import { Container, TextField, Grid, Box } from '@mui/material'
import { Container, TextField, Autocomplete, Grid, Box } from '@mui/material'
import ResponseForm from 'client/containers/TestApi/ResponseForm'
import { InputCode } from 'client/components/FormControl'
@ -36,7 +36,7 @@ function TestApi () {
const [name, setName] = useState(() => COMMANDS[0])
const [response, setResponse] = useState('')
const handleChangeCommand = evt => setName(evt?.target?.value)
const handleChangeCommand = (_, value) => setName(value)
const handleChangeResponse = res => setResponse(res)
return (
@ -46,23 +46,16 @@ function TestApi () {
>
<Grid container direction='row' spacing={2} className={classes.root}>
<Grid item xs={12} md={6}>
<TextField
fullWidth
select
<Autocomplete
disablePortal
color='secondary'
label={Tr(T.SelectRequest)}
options={useMemo(() => COMMANDS, [])}
value={name}
onChange={handleChangeCommand}
>
<option value=''>{Tr(T.None)}</option>
{useMemo(() =>
COMMANDS.map(commandName => (
<option key={`request-${commandName}`} value={commandName}>
{commandName}
</option>
), [])
renderInput={(params) => (
<TextField {...params} label={Tr(T.SelectRequest)} />
)}
</TextField>
/>
{name && name !== '' && (
<ResponseForm
handleChangeResponse={handleChangeResponse}

View File

@ -0,0 +1,58 @@
/* ------------------------------------------------------------------------- *
* Copyright 2002-2021, OpenNebula Project, OpenNebula Systems *
* *
* Licensed under the Apache License, Version 2.0 (the "License"); you may *
* not use this file except in compliance with the License. You may obtain *
* a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, software *
* distributed under the License is distributed on an "AS IS" BASIS, *
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
import { useMemo, JSXElementConstructor } from 'react'
import { Container, Grid, Button } from '@mui/material'
import { useForm, FormProvider } from 'react-hook-form'
import { object } from 'yup'
import { yupResolver } from '@hookform/resolvers/yup'
import { FormWithSchema } from 'client/components/Forms'
/**
* @returns {JSXElementConstructor}
* - Component that allows you to test a form and their components
*/
function TestForm () {
const fields = useMemo(() => [/* To add the fields validation */], [])
const resolver = useMemo(() => object() /* To add the form schema */, [])
const methods = useForm({
mode: 'onSubmit',
defaultValues: resolver.default(),
resolver: yupResolver(resolver, { isSubmit: true })
})
const onSubmit = values => {
console.log({ values })
}
return (
<Container component='form' onSubmit={methods.handleSubmit(onSubmit)}>
<Grid container direction='row' spacing={2}>
<Grid item xs={12}>
<FormProvider {...methods}>
<FormWithSchema fields={fields} />
</FormProvider>
</Grid>
<Grid item xs={12}>
<Button type='submit' variant='contained'>{'Submit'}</Button>
</Grid>
</Grid>
</Container>
)
}
export default TestForm

View File

@ -17,9 +17,11 @@ import loadable from '@loadable/component'
import { Code as DevIcon } from 'iconoir-react'
const TestApi = loadable(() => import('client/containers/TestApi'), { ssr: false })
const TestForm = loadable(() => import('client/containers/TestForm'), { ssr: false })
export const PATH = {
TEST_API: '/test-api'
TEST_API: '/test-api',
TEST_FORM: '/test-form'
}
export const ENDPOINTS = [
@ -30,6 +32,14 @@ export const ENDPOINTS = [
sidebar: true,
icon: DevIcon,
Component: TestApi
},
{
label: 'Test Form',
path: PATH.TEST_FORM,
devMode: true,
sidebar: true,
icon: DevIcon,
Component: TestForm
}
]