mirror of
https://github.com/OpenNebula/one.git
synced 2024-12-23 17:33:56 +03:00
parent
123e08cfd6
commit
9935e9916c
@ -19,6 +19,7 @@ const DialogForm = memo(
|
||||
const isMobile = useMediaQuery(theme => theme.breakpoints.only('xs'));
|
||||
|
||||
const { handleSubmit, ...methods } = useForm({
|
||||
mode: 'onChange',
|
||||
reValidateMode: 'onSubmit',
|
||||
defaultValues: values,
|
||||
resolver: yupResolver(resolver)
|
||||
|
@ -0,0 +1,72 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { TextField } from '@material-ui/core';
|
||||
import { Autocomplete } from '@material-ui/lab';
|
||||
import { Controller } from 'react-hook-form';
|
||||
|
||||
import ErrorHelper from 'client/components/FormControl/ErrorHelper';
|
||||
|
||||
const AutocompleteController = ({
|
||||
control,
|
||||
cy,
|
||||
name,
|
||||
label,
|
||||
values,
|
||||
error
|
||||
}) => (
|
||||
<Controller
|
||||
render={({ value: val, onBlur, onChange }) => {
|
||||
const selected = values.find(({ value }) => value === val) ?? null;
|
||||
|
||||
return (
|
||||
<Autocomplete
|
||||
fullWidth
|
||||
onBlur={onBlur}
|
||||
onChange={(_, newValue) => onChange(newValue.value)}
|
||||
options={values}
|
||||
value={selected}
|
||||
getOptionLabel={option => option.text}
|
||||
getOptionSelected={option => option.value === val}
|
||||
renderInput={({ inputProps, ...inputParams }) => (
|
||||
<TextField
|
||||
label={label}
|
||||
inputProps={{ ...inputProps, 'data-cy': cy }}
|
||||
error={Boolean(error)}
|
||||
helperText={
|
||||
Boolean(error) && <ErrorHelper label={error?.message} />
|
||||
}
|
||||
FormHelperTextProps={{ 'data-cy': `${cy}-error` }}
|
||||
{...inputParams}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
name={name}
|
||||
control={control}
|
||||
/>
|
||||
);
|
||||
|
||||
AutocompleteController.propTypes = {
|
||||
control: PropTypes.object,
|
||||
cy: PropTypes.string,
|
||||
name: PropTypes.string.isRequired,
|
||||
label: PropTypes.string,
|
||||
values: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
error: PropTypes.oneOfType([
|
||||
PropTypes.bool,
|
||||
PropTypes.objectOf(PropTypes.any)
|
||||
])
|
||||
};
|
||||
|
||||
AutocompleteController.defaultProps = {
|
||||
control: {},
|
||||
cy: 'cy',
|
||||
name: '',
|
||||
label: '',
|
||||
values: [],
|
||||
error: false
|
||||
};
|
||||
|
||||
export default AutocompleteController;
|
@ -19,7 +19,6 @@ const SelectController = memo(
|
||||
error={Boolean(error)}
|
||||
helperText={Boolean(error) && <ErrorHelper label={error?.message} />}
|
||||
FormHelperTextProps={{ 'data-cy': `${cy}-error` }}
|
||||
style={{ marginTop: 12 }}
|
||||
>
|
||||
{Array.isArray(values) &&
|
||||
values?.map(({ text, value }) => (
|
||||
|
@ -2,17 +2,19 @@ import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { Grid } from '@material-ui/core';
|
||||
import { useFormContext } from 'react-hook-form';
|
||||
import { useFormContext, useWatch } from 'react-hook-form';
|
||||
|
||||
import { TYPE_INPUT } from 'client/constants';
|
||||
import TextController from 'client/components/FormControl/TextController';
|
||||
import SelectController from 'client/components/FormControl/SelectController';
|
||||
import CheckboxController from 'client/components/FormControl/CheckboxController';
|
||||
import AutocompleteController from 'client/components/FormControl/AutocompleteController';
|
||||
|
||||
const InputController = {
|
||||
[TYPE_INPUT.TEXT]: TextController,
|
||||
[TYPE_INPUT.SELECT]: SelectController,
|
||||
[TYPE_INPUT.CHECKBOX]: CheckboxController
|
||||
[TYPE_INPUT.CHECKBOX]: CheckboxController,
|
||||
[TYPE_INPUT.AUTOCOMPLETE]: AutocompleteController
|
||||
};
|
||||
|
||||
const FormWithSchema = ({ id, cy, fields }) => {
|
||||
@ -20,11 +22,14 @@ const FormWithSchema = ({ id, cy, fields }) => {
|
||||
|
||||
return (
|
||||
<Grid container spacing={1}>
|
||||
{fields?.map(({ name, type, label, values }) => {
|
||||
{fields?.map(({ name, type, label, values, dependOf }) => {
|
||||
const dataCy = `${cy}-${name}`;
|
||||
const inputName = id ? `${id}.${name}` : name;
|
||||
const formError = id ? errors[id] : errors;
|
||||
const inputError = formError ? formError[name] : false;
|
||||
const dependValue = dependOf
|
||||
? useWatch({ control, name: id ? `${id}.${dependOf}` : dependOf })
|
||||
: null;
|
||||
|
||||
return (
|
||||
<Grid key={`${cy}-${name}`} item xs={12} md={6}>
|
||||
@ -34,7 +39,7 @@ const FormWithSchema = ({ id, cy, fields }) => {
|
||||
cy: dataCy,
|
||||
name: inputName,
|
||||
label,
|
||||
values,
|
||||
values: dependOf ? values(dependValue) : values,
|
||||
error: inputError
|
||||
})}
|
||||
</Grid>
|
||||
|
@ -71,11 +71,11 @@ Search.propTypes = {
|
||||
};
|
||||
|
||||
Search.defaultProps = {
|
||||
fullList: [],
|
||||
list: [],
|
||||
listOptions: {},
|
||||
renderResult: item => item,
|
||||
startAdornment: undefined,
|
||||
searchBoxProps: {}
|
||||
searchBoxProps: undefined
|
||||
};
|
||||
|
||||
export default Search;
|
||||
|
@ -33,6 +33,7 @@ module.exports = {
|
||||
TYPE_INPUT: {
|
||||
TEXT: 'text',
|
||||
SELECT: 'select',
|
||||
CHECKBOX: 'checkbox'
|
||||
CHECKBOX: 'checkbox',
|
||||
AUTOCOMPLETE: 'autocomplete'
|
||||
}
|
||||
};
|
||||
|
@ -23,7 +23,7 @@ export const FORM_FIELDS = [
|
||||
.min(5)
|
||||
.trim()
|
||||
.required('Name field is required')
|
||||
.default('One_service')
|
||||
.default('One_application')
|
||||
},
|
||||
{
|
||||
name: 'description',
|
||||
|
@ -19,7 +19,7 @@ const Clusters = () => {
|
||||
resolver: STEP_FORM_SCHEMA,
|
||||
onlyOneSelect: true,
|
||||
preRender: getClusters,
|
||||
list: clusters,
|
||||
list: clusters?.sort((a, b) => a.ID - b.ID),
|
||||
ItemComponent: ClusterCard
|
||||
}),
|
||||
[getClusters, clusters]
|
||||
|
@ -1,15 +1,7 @@
|
||||
import * as yup from 'yup';
|
||||
import { TYPE_INPUT } from 'client/constants';
|
||||
import { getValidationFromFields } from 'client/utils/helpers';
|
||||
|
||||
const DEFAULT_NETWORK = {
|
||||
mandatory: true,
|
||||
name: 'Public_dev',
|
||||
description: 'Public network in development mode',
|
||||
type: 'id',
|
||||
id: '0',
|
||||
extra: 'size=5'
|
||||
};
|
||||
import useOpennebula from 'client/hooks/useOpennebula';
|
||||
|
||||
export const SELECT = {
|
||||
template: 'template',
|
||||
@ -66,7 +58,27 @@ export const FORM_FIELDS = [
|
||||
{
|
||||
name: 'id',
|
||||
label: `Select a network`,
|
||||
type: TYPE_INPUT.TEXT,
|
||||
type: TYPE_INPUT.AUTOCOMPLETE,
|
||||
dependOf: 'type',
|
||||
values: dependValue => {
|
||||
const { vNetworks, vNetworksTemplates } = useOpennebula();
|
||||
const type = TYPES_NETWORKS.find(({ value }) => value === dependValue);
|
||||
|
||||
switch (type?.select) {
|
||||
case SELECT.network:
|
||||
return vNetworks.map(({ ID, NAME }) => ({
|
||||
text: NAME,
|
||||
value: ID
|
||||
}));
|
||||
case SELECT.template:
|
||||
return vNetworksTemplates.map(({ ID, NAME }) => ({
|
||||
text: NAME,
|
||||
value: ID
|
||||
}));
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
},
|
||||
validation: yup
|
||||
.string()
|
||||
.when('type', {
|
||||
@ -84,7 +96,7 @@ export const FORM_FIELDS = [
|
||||
.required('Network template is required field')
|
||||
})
|
||||
.required()
|
||||
.default('')
|
||||
.default(null)
|
||||
},
|
||||
{
|
||||
name: 'extra',
|
||||
@ -105,6 +117,4 @@ export const NETWORK_FORM_SCHEMA = yup.object(
|
||||
export const STEP_FORM_SCHEMA = yup
|
||||
.array()
|
||||
.of(NETWORK_FORM_SCHEMA)
|
||||
.min(2)
|
||||
.required()
|
||||
.default([DEFAULT_NETWORK, DEFAULT_NETWORK]);
|
||||
.default([]);
|
||||
|
Loading…
Reference in New Issue
Block a user