1
0
mirror of https://github.com/OpenNebula/one.git synced 2024-12-23 17:33:56 +03:00

F #3951: Add autocomplete component (#221)

This commit is contained in:
Sergio Betanzos 2020-09-17 15:40:09 +02:00 committed by GitHub
parent 123e08cfd6
commit 9935e9916c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 112 additions and 24 deletions

View File

@ -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)

View File

@ -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;

View File

@ -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 }) => (

View File

@ -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>

View File

@ -71,11 +71,11 @@ Search.propTypes = {
};
Search.defaultProps = {
fullList: [],
list: [],
listOptions: {},
renderResult: item => item,
startAdornment: undefined,
searchBoxProps: {}
searchBoxProps: undefined
};
export default Search;

View File

@ -33,6 +33,7 @@ module.exports = {
TYPE_INPUT: {
TEXT: 'text',
SELECT: 'select',
CHECKBOX: 'checkbox'
CHECKBOX: 'checkbox',
AUTOCOMPLETE: 'autocomplete'
}
};

View File

@ -23,7 +23,7 @@ export const FORM_FIELDS = [
.min(5)
.trim()
.required('Name field is required')
.default('One_service')
.default('One_application')
},
{
name: 'description',

View File

@ -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]

View File

@ -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([]);