fix(client):format url values on form submit

This commit is contained in:
Valeriy
2019-06-17 23:40:47 +03:00
committed by mrugesh
parent c99366fa71
commit fbb8311af7
3 changed files with 38 additions and 38 deletions

View File

@ -2,7 +2,12 @@ import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { reduxForm } from 'redux-form'; import { reduxForm } from 'redux-form';
import { FormFields, BlockSaveButton, BlockSaveWrapper } from './'; import {
FormFields,
BlockSaveButton,
BlockSaveWrapper,
formatUrlValues
} from './';
const propTypes = { const propTypes = {
buttonText: PropTypes.string, buttonText: PropTypes.string,
@ -48,7 +53,9 @@ export function DynamicForm({
return ( return (
<form <form
id={`dynamic-${id}`} id={`dynamic-${id}`}
onSubmit={handleSubmit(submit)} onSubmit={handleSubmit((values, ...args) =>
submit(formatUrlValues(values, options), ...args)
)}
style={{ width: '100%' }} style={{ width: '100%' }}
> >
<FormFields <FormFields

View File

@ -15,6 +15,16 @@ export function callIfDefined(fn) {
return value => (value ? fn(value) : value); return value => (value ? fn(value) : value);
} }
export function formatUrlValues(values, options) {
return Object.keys(values).reduce((result, key) => {
let value = values[key];
if (options.types[key] === 'url') {
value = normalizeUrl(value, normalizeOptions);
}
return { ...result, [key]: value };
}, {});
}
// formatUrl(url: String) => String // formatUrl(url: String) => String
export function formatUrl(url) { export function formatUrl(url) {
if (typeof url === 'string' && url.length > 4 && url.indexOf('.') !== -1) { if (typeof url === 'string' && url.length > 4 && url.indexOf('.') !== -1) {

View File

@ -2,9 +2,8 @@ import React, { Component } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { Grid, Col, Row } from '@freecodecamp/react-bootstrap'; import { Grid, Col, Row } from '@freecodecamp/react-bootstrap';
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import { reduxForm } from 'redux-form'; import { connect } from 'react-redux';
import { graphql } from 'gatsby'; import { graphql } from 'gatsby';
import normalizeUrl from 'normalize-url';
import { import {
executeChallenge, executeChallenge,
@ -28,53 +27,44 @@ import CompletionModal from '../components/CompletionModal';
import HelpModal from '../components/HelpModal'; import HelpModal from '../components/HelpModal';
import ProjectToolPanel from '../project/Tool-Panel'; import ProjectToolPanel from '../project/Tool-Panel';
import ProjectForm from '../project/ProjectForm'; import ProjectForm from '../project/ProjectForm';
import { import { Form } from '../../../components/formHelpers';
createFormValidator,
isValidURL,
makeRequired,
Form
} from '../../../components/formHelpers';
import Spacer from '../../../components/helpers/Spacer'; import Spacer from '../../../components/helpers/Spacer';
import { ChallengeNode } from '../../../redux/propTypes';
import { isSignedInSelector } from '../../../redux';
import { backend } from '../../../../utils/challengeTypes'; import { backend } from '../../../../utils/challengeTypes';
import '../components/test-frame.css'; import '../components/test-frame.css';
// provided by redux form
const reduxFormPropTypes = {
fields: PropTypes.object,
handleSubmit: PropTypes.func.isRequired,
resetForm: PropTypes.func.isRequired,
submitting: PropTypes.bool
};
const propTypes = { const propTypes = {
challengeMounted: PropTypes.func.isRequired, challengeMounted: PropTypes.func.isRequired,
data: PropTypes.shape({
challengeNode: ChallengeNode
}),
description: PropTypes.string, description: PropTypes.string,
executeChallenge: PropTypes.func.isRequired, executeChallenge: PropTypes.func.isRequired,
id: PropTypes.string, id: PropTypes.string,
initTests: PropTypes.func.isRequired, initTests: PropTypes.func.isRequired,
isSignedIn: PropTypes.bool,
output: PropTypes.string, output: PropTypes.string,
pageContext: PropTypes.shape({
challengeMeta: PropTypes.object
}),
tests: PropTypes.array, tests: PropTypes.array,
title: PropTypes.string, title: PropTypes.string,
updateBackendFormValues: PropTypes.func.isRequired, updateBackendFormValues: PropTypes.func.isRequired,
updateChallengeMeta: PropTypes.func.isRequired, updateChallengeMeta: PropTypes.func.isRequired,
updateProjectFormValues: PropTypes.func.isRequired, updateProjectFormValues: PropTypes.func.isRequired
...reduxFormPropTypes
};
const fields = ['solution'];
const fieldValidators = {
solution: makeRequired(isValidURL)
}; };
const mapStateToProps = createSelector( const mapStateToProps = createSelector(
consoleOutputSelector, consoleOutputSelector,
challengeTestsSelector, challengeTestsSelector,
(output, tests) => ({ isSignedInSelector,
(output, tests, isSignedIn) => ({
tests, tests,
output output,
isSignedIn
}) })
); );
@ -158,7 +148,6 @@ export class BackEnd extends Component {
handleSubmit(values) { handleSubmit(values) {
const { updateBackendFormValues, executeChallenge } = this.props; const { updateBackendFormValues, executeChallenge } = this.props;
values.solution = normalizeUrl(values.solution);
updateBackendFormValues(values); updateBackendFormValues(values);
executeChallenge(); executeChallenge();
} }
@ -176,13 +165,12 @@ export class BackEnd extends Component {
}, },
output, output,
tests, tests,
submitting, isSignedIn,
executeChallenge, executeChallenge,
updateProjectFormValues updateProjectFormValues
} = this.props; } = this.props;
// TODO: Should be tied to user.isSignedIn const buttonCopy = isSignedIn
const buttonCopy = submitting
? 'Submit and go to my next challenge' ? 'Submit and go to my next challenge'
: "I've completed this challenge"; : "I've completed this challenge";
const blockNameTitle = `${blockName} - ${title}`; const blockNameTitle = `${blockName} - ${title}`;
@ -242,12 +230,7 @@ export class BackEnd extends Component {
BackEnd.displayName = 'BackEnd'; BackEnd.displayName = 'BackEnd';
BackEnd.propTypes = propTypes; BackEnd.propTypes = propTypes;
export default reduxForm( export default connect(
{
form: 'BackEndChallenge',
fields,
validate: createFormValidator(fieldValidators)
},
mapStateToProps, mapStateToProps,
mapDispatchToActions mapDispatchToActions
)(BackEnd); )(BackEnd);