diff --git a/.eslintrc.js b/.eslintrc.js
index 3c76d5678..1932d38cf 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -24,6 +24,13 @@ module.exports = {
"aspects": ["invalidHref", "preferButton"]
}],
"jsx-a11y/click-events-have-key-events": 0,
+ "jsx-a11y/label-has-for": [2, {
+ "components": ["Label"],
+ "required": {
+ "every": ["id"]
+ },
+ "allowChildren": false
+ }],
"react/no-array-index-key": 0,
"max-len": 0,
"react/no-danger": 0,
diff --git a/demo/collections/User.js b/demo/collections/User.js
index 36d257861..b34a5c984 100644
--- a/demo/collections/User.js
+++ b/demo/collections/User.js
@@ -8,6 +8,7 @@ module.exports = {
},
useAsTitle: 'email',
useAsUsername: 'email',
+ passwordIndex: 1,
policies: {
create: (req, res, next) => {
return next();
diff --git a/src/client/api.js b/src/client/api.js
index 52f0b95a0..8c4c2efd9 100644
--- a/src/client/api.js
+++ b/src/client/api.js
@@ -21,18 +21,20 @@ const requests = {
post: (url, body) =>
fetch(`${url}`, {
method: 'post',
- body,
+ body: JSON.stringify(body),
headers: {
- ...setJWT()
+ ...setJWT(),
+ 'Content-Type': 'application/json',
},
}),
put: (url, body) =>
fetch(`${url}`, {
method: 'put',
- body,
+ body: JSON.stringify(body),
headers: {
- ...setJWT()
+ ...setJWT(),
+ 'Content-Type': 'application/json',
},
}),
};
diff --git a/src/client/components/Routes.js b/src/client/components/Routes.js
index d6e0e094d..3269e500d 100644
--- a/src/client/components/Routes.js
+++ b/src/client/components/Routes.js
@@ -1,4 +1,4 @@
-import React, { useState, useEffect } from 'react';
+import React, { useState, useEffect, Fragment } from 'react';
import Cookies from 'universal-cookie';
import {
Route, Switch, withRouter, Redirect,
@@ -56,67 +56,71 @@ const Routes = () => {
if (cookies.get('token')) {
return (
-
-
-
+
+
+
+
- {config.collections.map((collection) => {
- const components = collection.components ? collection.components : {};
- return (
-
- {
- return (
-
- );
- }}
- />
+ {config.collections.map((collection) => {
+ const components = collection.components ? collection.components : {};
+ return (
+
+ {
+ return (
+
+ );
+ }}
+ />
- {
- return (
-
- );
- }}
- />
+ {
+ return (
+
+ );
+ }}
+ />
- {
- const ListComponent = components.List ? components.List : List;
- return (
-
- );
- }}
- />
-
-
- );
- })}
+ {
+ const ListComponent = components.List ? components.List : List;
+ return (
+
+ );
+ }}
+ />
+
+ );
+ })}
+
+ Not Found
+
+
);
}
diff --git a/src/client/components/forms/Form/index.js b/src/client/components/forms/Form/index.js
index b42fdabf6..63b9727eb 100644
--- a/src/client/components/forms/Form/index.js
+++ b/src/client/components/forms/Form/index.js
@@ -70,6 +70,8 @@ const Form = (props) => {
setProcessing(true);
+ console.log(data);
+
// Make the API call from the action
api.requests[method.toLowerCase()](action, data).then(
(res) => {
diff --git a/src/client/components/forms/field-types/fieldType/index.js b/src/client/components/forms/field-types/fieldType/index.js
index 5053b76cc..d9319e34f 100644
--- a/src/client/components/forms/field-types/fieldType/index.js
+++ b/src/client/components/forms/field-types/fieldType/index.js
@@ -1,117 +1,163 @@
-import React, { Component } from 'react';
-import FormContext from '../../Form/Context'
+import React, { useContext, useEffect } from 'react';
+import PropTypes from 'prop-types';
+import FormContext from '../../Form/Context';
+import Tooltip from '../../../modules/Tooltip';
import './index.scss';
-const fieldType = (PassedComponent, type, validate, errors) => {
+const baseClass = 'field-type';
- class FieldType extends Component {
+const asFieldType = (PassedComponent, type, validate, errors) => {
+ const FieldType = (props) => {
+ const formContext = useContext(FormContext);
- constructor(props) {
- super(props);
+ const {
+ name,
+ id,
+ value,
+ required,
+ initialValue,
+ valueOverride,
+ onChange,
+ } = props;
- this.state = {
- init: false
- };
- }
-
- sendField(value) {
- this.props.context.setValue({
- name: this.props.name,
- value: value,
- valid: this.props.required && validate
- ? validate(value || '', this.props.type)
- : true
+ const sendField = (valueToSend) => {
+ formContext.setValue({
+ name,
+ value: valueToSend,
+ valid: required && validate
+ ? validate(valueToSend || '', type)
+ : true,
});
- }
+ };
- componentDidMount() {
- let value = this.props.value ? this.props.value : '';
- value = this.props.initialValue ? this.props.initialValue : value;
- value = this.props.valueOverride ? this.props.valueOverride : value;
- this.sendField(value);
+ useEffect(() => {
+ let valueToInitialize = value;
+ if (initialValue) valueToInitialize = initialValue;
+ if (valueOverride) valueToInitialize = valueOverride;
+ sendField(valueToInitialize);
+ }, []);
- this.setState({
- init: true
- });
- }
+ useEffect(() => {
+ sendField(valueOverride);
+ }, [valueOverride]);
- componentDidUpdate(prevProps) {
- if (prevProps.valueOverride !== this.props.valueOverride) {
- this.sendField(this.props.valueOverride);
- }
+ useEffect(() => {
+ sendField(initialValue);
+ }, [initialValue]);
- if (prevProps.initialValue !== this.props.initialValue) {
- this.sendField(this.props.initialValue);
- }
- }
+ const classList = [baseClass, type];
+ const valid = formContext.fields[name] ? formContext.fields[name].valid : true;
+ const showError = valid === false && formContext.submitted;
- render() {
- const valid = this.props.context.fields[this.props.name]
- ? this.props.context.fields[this.props.name].valid
- : true;
+ if (showError) classList.push('error');
- const showError = valid === false && this.props.context.submitted;
+ let valueToRender = formContext.fields[name] ? formContext.fields[name].value : '';
- let className = `field-type ${type}${showError ? ' error' : ''}`;
+ // If valueOverride present, field is being controlled by state outside form
+ valueToRender = valueOverride || value;
- let value = this.props.context.fields[this.props.name] ? this.props.context.fields[this.props.name].value : '';
+ const classes = classList.filter(Boolean).join(' ');
- // If valueOverride present, field is being controlled by state outside form
- value = this.props.valueOverride ? this.props.valueOverride : value;
-
- return (
- }
- error={}
- onChange={e => {
- this.sendField(e.target.value);
- this.props.onChange && this.props.onChange(e);
- }} />
- )
- }
- }
-
- const Label = props => {
- if (props.label) {
- return (
-
- )
- }
-
- return null;
- }
-
- const Error = props => {
- if (props.showError) {
- return (
-
- {props.error && errors[props.error]}
-
- {!props.error && errors}
-
- )
- }
-
- return null;
- }
-
- const FieldTypeWithContext = props => {
return (
-
- {context => }
-
+
+ )}
+ error={(
+
+ )}
+ onChange={(e) => {
+ sendField(e.target.value);
+ if (onChange && typeof onChange === 'function') onChange(e);
+ }}
+ />
);
};
- return FieldTypeWithContext;
-}
+ FieldType.defaultProps = {
+ value: '',
+ required: false,
+ initialValue: '',
+ valueOverride: '',
+ onChange: null,
+ id: '',
+ };
-export default fieldType;
+ FieldType.propTypes = {
+ name: PropTypes.string.isRequired,
+ value: PropTypes.string,
+ required: PropTypes.bool,
+ type: PropTypes.string.isRequired,
+ initialValue: PropTypes.string,
+ valueOverride: PropTypes.string,
+ onChange: PropTypes.func,
+ id: PropTypes.string,
+ };
+
+ const Label = (props) => {
+ const {
+ label, required, htmlFor,
+ } = props;
+
+ if (label) {
+ return (
+
+ );
+ }
+
+ return null;
+ };
+
+ Label.defaultProps = {
+ required: false,
+ };
+
+ Label.propTypes = {
+ label: PropTypes.string.isRequired,
+ htmlFor: PropTypes.string.isRequired,
+ required: PropTypes.bool,
+ };
+
+ const Error = (props) => {
+ const { error, showError } = props;
+
+ if (showError) {
+ return (
+
+ {error && errors[error]}
+ {!error && errors}
+
+ );
+ }
+
+ return null;
+ };
+
+ Error.defaultProps = {
+ showError: false,
+ };
+
+ Error.propTypes = {
+ error: PropTypes.string.isRequired,
+ showError: PropTypes.bool,
+ };
+
+ return FieldType;
+};
+
+export default asFieldType;
diff --git a/src/client/components/layout/DefaultTemplate/index.js b/src/client/components/layout/DefaultTemplate/index.js
index 0bad7cabc..fc87d7732 100644
--- a/src/client/components/layout/DefaultTemplate/index.js
+++ b/src/client/components/layout/DefaultTemplate/index.js
@@ -1,6 +1,7 @@
import React from 'react';
+import PropTypes from 'prop-types';
import Sidebar from '../Sidebar';
-import StepNav from '../../modules/StepNav';
+import StepNav, { StepNavProvider } from '../../modules/StepNav';
import Localizer from '../../modules/Localizer';
import './index.scss';
@@ -9,15 +10,24 @@ const DefaultTemplate = ({ children }) => {
return (
-
-
-
-
-
- {children}
+
+
+
+
+
+
+ {children}
+
);
};
+DefaultTemplate.propTypes = {
+ children: PropTypes.oneOfType([
+ PropTypes.arrayOf(PropTypes.node),
+ PropTypes.node,
+ ]).isRequired,
+};
+
export default DefaultTemplate;
diff --git a/src/client/components/layout/Sidebar/index.js b/src/client/components/layout/Sidebar/index.js
index 2955aa5dd..93de21107 100644
--- a/src/client/components/layout/Sidebar/index.js
+++ b/src/client/components/layout/Sidebar/index.js
@@ -1,6 +1,5 @@
import React from 'react';
-import { withRouter, NavLink, Link } from 'react-router-dom';
-import { connect } from 'react-redux';
+import { useLocation, NavLink, Link } from 'react-router-dom';
import config from 'payload-config';
import Arrow from '../../graphics/Arrow';
@@ -8,11 +7,7 @@ import Icon from '../../graphics/Icon';
import './index.scss';
-const mapState = state => ({
- config: state.common.config,
-});
-
-const Sidebar = (props) => {
+const Sidebar = () => {
const {
collections,
globals,
@@ -21,6 +16,8 @@ const Sidebar = (props) => {
},
} = config;
+ const location = useLocation();
+
return (