Make optional fields configurable (#234)
Making optional fields configurable will help us in enabling and disabling fields as required. VAN-405
This commit is contained in:
committed by
Waheed Ahmed
parent
acb0f23f0a
commit
43e0372be5
@@ -23,7 +23,7 @@ AUTHN_MINIMAL_HEADER=true
|
||||
LOGIN_ISSUE_SUPPORT_LINK=''
|
||||
TOS_AND_HONOR_CODE='http://localhost:18000/honor'
|
||||
PRIVACY_POLICY='http://localhost:18000/privacy'
|
||||
REGISTRATION_OPTIONAL_FIELDS='gender,goals,level_of_education,year_of_birth'
|
||||
REGISTRATION_OPTIONAL_FIELDS='gender,goals,levelOfEducation,yearOfBirth'
|
||||
USER_SURVEY_COOKIE_NAME='openedx-user-survey-type'
|
||||
COOKIE_DOMAIN='localhost'
|
||||
WELCOME_PAGE_SUPPORT_LINK='http://localhost:1999/welcome'
|
||||
|
||||
@@ -9,7 +9,9 @@ import messages from './messages';
|
||||
import { AuthnValidationFormGroup } from '../common-components';
|
||||
|
||||
const OptionalFields = (props) => {
|
||||
const { intl, onChangeHandler, values } = props;
|
||||
const {
|
||||
intl, optionalFields, onChangeHandler, values,
|
||||
} = props;
|
||||
|
||||
const getOptions = () => ({
|
||||
yearOfBirthOptions: [{
|
||||
@@ -28,59 +30,65 @@ const OptionalFields = (props) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<AuthnValidationFormGroup
|
||||
label={intl.formatMessage(messages['registration.field.gender.options.label'])}
|
||||
for="gender"
|
||||
name="gender"
|
||||
type="select"
|
||||
key="gender"
|
||||
value={values.gender}
|
||||
className="mb-20 opt-inline-field data-hj-suppress"
|
||||
onChange={(e) => onChangeHandler('gender', e.target.value)}
|
||||
selectOptions={getOptions().genderOptions}
|
||||
inputFieldStyle="border-gray-600 custom-select-size"
|
||||
/>
|
||||
<AuthnValidationFormGroup
|
||||
label={intl.formatMessage(messages['registration.year.of.birth.label'])}
|
||||
for="yearOfBirth"
|
||||
name="yearOfBirth"
|
||||
type="select"
|
||||
key="yearOfBirth"
|
||||
value={values.yearOfBirth}
|
||||
className="mb-20 opt-inline-field opt-year-field data-hj-suppress"
|
||||
onChange={(e) => onChangeHandler('yearOfBirth', e.target.value)}
|
||||
selectOptions={getOptions().yearOfBirthOptions}
|
||||
inputFieldStyle="border-gray-600 custom-select-size"
|
||||
/>
|
||||
<AuthnValidationFormGroup
|
||||
label={intl.formatMessage(messages['registration.field.education.levels.label'])}
|
||||
for="levelOfEducation"
|
||||
name="levelOfEducation"
|
||||
type="select"
|
||||
key="levelOfEducation"
|
||||
value={values.levelOfEducation}
|
||||
className="mb-20 data-hj-suppress"
|
||||
onChange={(e) => onChangeHandler('levelOfEducation', e.target.value)}
|
||||
selectOptions={getOptions().educationLevelOptions}
|
||||
inputFieldStyle="border-gray-600 custom-select-size"
|
||||
/>
|
||||
<AuthnValidationFormGroup
|
||||
label={intl.formatMessage(messages['registration.goals.label'])}
|
||||
for="goals"
|
||||
name="goals"
|
||||
type="textarea"
|
||||
key="goals"
|
||||
value={values.goals}
|
||||
className="mb-20"
|
||||
onChange={(e) => onChangeHandler('goals', e.target.value)}
|
||||
inputFieldStyle="border-gray-600 custom-select-size"
|
||||
/>
|
||||
{optionalFields.includes('gender') && (
|
||||
<AuthnValidationFormGroup
|
||||
label={intl.formatMessage(messages['registration.field.gender.options.label'])}
|
||||
for="gender"
|
||||
name="gender"
|
||||
type="select"
|
||||
key="gender"
|
||||
value={values.gender}
|
||||
className="mb-20 data-hj-suppress"
|
||||
onChange={(e) => onChangeHandler('gender', e.target.value)}
|
||||
selectOptions={getOptions().genderOptions}
|
||||
/>
|
||||
)}
|
||||
{optionalFields.includes('yearOfBirth') && (
|
||||
<AuthnValidationFormGroup
|
||||
label={intl.formatMessage(messages['registration.year.of.birth.label'])}
|
||||
for="yearOfBirth"
|
||||
name="yearOfBirth"
|
||||
type="select"
|
||||
key="yearOfBirth"
|
||||
value={values.yearOfBirth}
|
||||
className="mb-20 data-hj-suppress"
|
||||
onChange={(e) => onChangeHandler('yearOfBirth', e.target.value)}
|
||||
selectOptions={getOptions().yearOfBirthOptions}
|
||||
/>
|
||||
)}
|
||||
{optionalFields.includes('levelOfEducation') && (
|
||||
<AuthnValidationFormGroup
|
||||
label={intl.formatMessage(messages['registration.field.education.levels.label'])}
|
||||
for="levelOfEducation"
|
||||
name="levelOfEducation"
|
||||
type="select"
|
||||
key="levelOfEducation"
|
||||
value={values.levelOfEducation}
|
||||
className="mb-20 data-hj-suppress"
|
||||
onChange={(e) => onChangeHandler('levelOfEducation', e.target.value)}
|
||||
selectOptions={getOptions().educationLevelOptions}
|
||||
/>
|
||||
)}
|
||||
{optionalFields.includes('goals') && (
|
||||
<AuthnValidationFormGroup
|
||||
label={intl.formatMessage(messages['registration.goals.label'])}
|
||||
for="goals"
|
||||
name="goals"
|
||||
type="textarea"
|
||||
key="goals"
|
||||
value={values.goals}
|
||||
className="mb-20"
|
||||
onChange={(e) => onChangeHandler('goals', e.target.value)}
|
||||
inputFieldStyle="border-gray-600"
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
OptionalFields.propTypes = {
|
||||
intl: intlShape.isRequired,
|
||||
optionalFields: PropTypes.arrayOf(PropTypes.string).isRequired,
|
||||
onChangeHandler: PropTypes.func.isRequired,
|
||||
values: PropTypes.shape({
|
||||
gender: PropTypes.string,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
|
||||
import camelCase from 'lodash.camelcase';
|
||||
import snakeCase from 'lodash.snakecase';
|
||||
import { connect } from 'react-redux';
|
||||
import Skeleton from 'react-loading-skeleton';
|
||||
import { Helmet } from 'react-helmet';
|
||||
@@ -44,16 +44,14 @@ class RegistrationPage extends React.Component {
|
||||
this.queryParams = getAllPossibleQueryParam();
|
||||
this.tpaHint = getTpaHint();
|
||||
|
||||
const optionalFields = getConfig().REGISTRATION_OPTIONAL_FIELDS ? getConfig().REGISTRATION_OPTIONAL_FIELDS.split(',') : [];
|
||||
|
||||
this.state = {
|
||||
email: '',
|
||||
name: '',
|
||||
username: '',
|
||||
password: '',
|
||||
country: '',
|
||||
gender: '',
|
||||
yearOfBirth: '',
|
||||
goals: '',
|
||||
levelOfEducation: '',
|
||||
enableOptionalField: false,
|
||||
validationAlertMessages: {
|
||||
name: [{ user_message: '' }],
|
||||
@@ -71,6 +69,8 @@ class RegistrationPage extends React.Component {
|
||||
},
|
||||
institutionLogin: false,
|
||||
formValid: false,
|
||||
optionalFields,
|
||||
optionalFieldsState: {},
|
||||
startTime: Date.now(),
|
||||
updateFieldErrors: false,
|
||||
updateAlertErrors: false,
|
||||
@@ -144,16 +144,17 @@ class RegistrationPage extends React.Component {
|
||||
}
|
||||
|
||||
getOptionalFields() {
|
||||
const values = {};
|
||||
const optionalFields = getConfig().REGISTRATION_OPTIONAL_FIELDS.split(',');
|
||||
optionalFields.forEach((key) => {
|
||||
values[camelCase(key)] = this.state[camelCase(key)];
|
||||
});
|
||||
|
||||
return (
|
||||
<OptionalFields
|
||||
values={values}
|
||||
onChangeHandler={(fieldName, value) => { this.setState({ [fieldName]: value }); }}
|
||||
optionalFields={this.state.optionalFields}
|
||||
values={this.state.optionalFieldsState}
|
||||
onChangeHandler={
|
||||
(fieldName, value) => {
|
||||
this.setState(prevState => ({
|
||||
optionalFieldsState: { ...prevState.optionalFieldsState, [fieldName]: value },
|
||||
}));
|
||||
}
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -190,11 +191,9 @@ class RegistrationPage extends React.Component {
|
||||
}
|
||||
// Since optional fields are not validated we can add it to payload after required fields
|
||||
// have been validated. This will save us unwanted calls to validateInput()
|
||||
const optionalFields = getConfig().REGISTRATION_OPTIONAL_FIELDS.split(',');
|
||||
optionalFields.forEach((key) => {
|
||||
const stateKey = camelCase(key);
|
||||
if (this.state[stateKey]) {
|
||||
payload[key] = this.state[stateKey];
|
||||
this.state.optionalFields.forEach((key) => {
|
||||
if (this.state.optionalFieldsState[key]) {
|
||||
payload[snakeCase(key)] = this.state.optionalFieldsState[key];
|
||||
}
|
||||
});
|
||||
if (finalValidation) {
|
||||
|
||||
@@ -27,7 +27,7 @@ const mockStore = configureStore();
|
||||
describe('RegistrationPageTests', () => {
|
||||
mergeConfig({
|
||||
PRIVACY_POLICY: 'http://privacy-policy.com',
|
||||
REGISTRATION_OPTIONAL_FIELDS: 'gender,goals,level_of_education,year_of_birth',
|
||||
REGISTRATION_OPTIONAL_FIELDS: 'gender,goals,levelOfEducation,yearOfBirth',
|
||||
TOS_AND_HONOR_CODE: 'http://tos-and-honot-code.com',
|
||||
USER_SURVEY_COOKIE_NAME: process.env.USER_SURVEY_COOKIE_NAME,
|
||||
});
|
||||
@@ -189,7 +189,7 @@ describe('RegistrationPageTests', () => {
|
||||
expect(registrationPage.find('input#optional').length).toEqual(0);
|
||||
|
||||
mergeConfig({
|
||||
REGISTRATION_OPTIONAL_FIELDS: 'gender,goals,level_of_education,year_of_birth',
|
||||
REGISTRATION_OPTIONAL_FIELDS: 'gender,goals,levelOfEducation,yearOfBirth',
|
||||
});
|
||||
|
||||
registrationPage = mount(reduxWrapper(<IntlRegistrationPage {...props} />));
|
||||
|
||||
Reference in New Issue
Block a user