diff --git a/demo/collections/User.js b/demo/collections/User.js index ef41822127..36d2578611 100644 --- a/demo/collections/User.js +++ b/demo/collections/User.js @@ -38,8 +38,9 @@ module.exports = { }, { name: 'role', - type: 'enum', - enum: roles, + label: 'Role', + type: 'select', + options: roles, default: 'user', }, ], diff --git a/src/client/components/Routes.js b/src/client/components/Routes.js index 088c48cd66..d6e0e094df 100644 --- a/src/client/components/Routes.js +++ b/src/client/components/Routes.js @@ -37,12 +37,12 @@ const Routes = () => { - - - + ); - } if (initialized === true) { + } + + if (initialized === true) { return ( diff --git a/src/client/components/forms/RenderFields/index.js b/src/client/components/forms/RenderFields/index.js index de72f35137..419e3550b2 100644 --- a/src/client/components/forms/RenderFields/index.js +++ b/src/client/components/forms/RenderFields/index.js @@ -2,11 +2,41 @@ import React from 'react'; import PropTypes from 'prop-types'; import fieldTypes from '../field-types'; +import './index.scss'; + +const baseClass = 'render-fields'; + const RenderFields = ({ fields }) => { if (fields) { - return fields.map((field, i) => { - return field.name + i; - }); + return ( +
+ {fields.map((field, i) => { + const FieldComponent = field.component || fieldTypes[field.type]; + + if (FieldComponent) { + return ( + + ); + } + + return ( +
+ No matched field found for + {' '} + " + {field.label} + " +
+ ); + })} +
+ ); } return null; diff --git a/src/client/components/forms/RenderFields/index.scss b/src/client/components/forms/RenderFields/index.scss new file mode 100644 index 0000000000..1cb6724cd1 --- /dev/null +++ b/src/client/components/forms/RenderFields/index.scss @@ -0,0 +1,7 @@ +@import '../../../scss/styles'; + +.render-fields { + &__no-field-found { + @include gutter; + } +} diff --git a/src/client/components/forms/field-types/Input/index.js b/src/client/components/forms/field-types/Input/index.js index 3ac82a58a5..2545f80a91 100644 --- a/src/client/components/forms/field-types/Input/index.js +++ b/src/client/components/forms/field-types/Input/index.js @@ -7,22 +7,36 @@ const error = 'Please fill in the field'; const validate = value => value.length > 0; -const Input = props => { +const Input = (props) => { + const { + className, + style, + width, + error, + label, + value, + onChange, + disabled, + placeholder, + id, + name, + } = props; + return ( -
- {props.error} - {props.label} + {error} + {label} + id={id ? id : name} + name={name} />
); } diff --git a/src/client/components/forms/field-types/Select/index.js b/src/client/components/forms/field-types/Select/index.js new file mode 100644 index 0000000000..e688d5d699 --- /dev/null +++ b/src/client/components/forms/field-types/Select/index.js @@ -0,0 +1,103 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import fieldType from '../fieldType'; + +import './index.scss'; + +const errorMessage = 'Please fill in the textarea'; + +const validate = value => value.length > 0; + +const Select = (props) => { + const { + className, + style, + error, + label, + value, + onChange, + disabled, + placeholder, + id, + name, + options, + } = props; + + return ( +
+ {error} + {label} + +
+ ); +}; + +Select.defaultProps = { + className: null, + style: {}, + error: null, + label: null, + value: '', + onChange: null, + disabled: null, + placeholder: null, + id: null, + name: 'select', +}; + +Select.propTypes = { + className: PropTypes.string, + style: PropTypes.shape({}), + error: PropTypes.node, + label: PropTypes.node, + value: PropTypes.string, + onChange: PropTypes.func, + disabled: PropTypes.string, + placeholder: PropTypes.string, + id: PropTypes.string, + name: PropTypes.string, + options: PropTypes.oneOfType([ + PropTypes.arrayOf( + PropTypes.string, + ), + PropTypes.arrayOf( + PropTypes.shape({ + value: PropTypes.string, + label: PropTypes.string, + }), + ), + ]).isRequired, +}; + +export default fieldType(Select, 'select', validate, errorMessage); diff --git a/src/client/components/forms/field-types/Select/index.scss b/src/client/components/forms/field-types/Select/index.scss new file mode 100644 index 0000000000..64a229d171 --- /dev/null +++ b/src/client/components/forms/field-types/Select/index.scss @@ -0,0 +1,16 @@ +@import '../../../../scss//styles'; + +.field-type.select { + margin-bottom: base(.5); + position: relative; + + select { + @include formInput(); + } + + &.error { + select { + background-color: lighten($error, 20%); + } + } +} diff --git a/src/client/components/forms/field-types/index.js b/src/client/components/forms/field-types/index.js index 984427ddf9..ad01a4c2d1 100644 --- a/src/client/components/forms/field-types/index.js +++ b/src/client/components/forms/field-types/index.js @@ -1,8 +1,21 @@ -export { default as Email } from './Email'; -export { default as Group } from './Group'; -export { default as HiddenInput } from './HiddenInput'; -export { default as Input } from './Input'; -export { default as Media } from './Media'; -export { default as Password } from './Password'; -export { default as Repeater } from './Repeater'; -export { default as Textarea } from './Textarea'; +import email from './Email'; +import group from './Group'; +import hidden from './HiddenInput'; +import input from './Input'; +import media from './Media'; +import password from './Password'; +import repeater from './Repeater'; +import textarea from './Textarea'; +import select from './Select'; + +export default { + email, + group, + hidden, + input, + media, + password, + repeater, + textarea, + select, +}; diff --git a/src/mongoose/schema/fieldToSchemaMap.js b/src/mongoose/schema/fieldToSchemaMap.js index c65eea33de..d39a72c7c1 100644 --- a/src/mongoose/schema/fieldToSchemaMap.js +++ b/src/mongoose/schema/fieldToSchemaMap.js @@ -54,11 +54,14 @@ const fieldToSchemaMap = { }); return [schema]; }, - enum: (field) => { + select: (field) => { return { ...formatBaseSchema(field), type: String, - enum: field.enum, + enum: field.options.map((option) => { + if (typeof option === 'object') return option.value; + return option; + }), }; }, flexible: (field) => {