From d86d7a63e764bf065ae499ce09a41cc87a58ed8e Mon Sep 17 00:00:00 2001 From: dpwrussell Date: Wed, 14 Dec 2016 15:33:23 -0500 Subject: [PATCH 1/2] Add selectors for submitting, submitSucceeded and submitFailed --- src/createAll.js | 6 +++ src/immutable.js | 3 ++ src/index.js | 3 ++ .../__tests__/hasSubmitFailed.spec.js | 47 +++++++++++++++++++ .../__tests__/hasSubmitSucceeded.spec.js | 47 +++++++++++++++++++ src/selectors/__tests__/isSubmitting.spec.js | 47 +++++++++++++++++++ src/selectors/hasSubmitFailed.js | 8 ++++ src/selectors/hasSubmitSucceeded.js | 8 ++++ src/selectors/isSubmitting.js | 8 ++++ 9 files changed, 177 insertions(+) create mode 100644 src/selectors/__tests__/hasSubmitFailed.spec.js create mode 100644 src/selectors/__tests__/hasSubmitSucceeded.spec.js create mode 100644 src/selectors/__tests__/isSubmitting.spec.js create mode 100644 src/selectors/hasSubmitFailed.js create mode 100644 src/selectors/hasSubmitSucceeded.js create mode 100644 src/selectors/isSubmitting.js diff --git a/src/createAll.js b/src/createAll.js index 404fa471d..12e2f0a45 100755 --- a/src/createAll.js +++ b/src/createAll.js @@ -12,6 +12,9 @@ import createIsDirty from './selectors/isDirty' import createIsInvalid from './selectors/isInvalid' import createIsPristine from './selectors/isPristine' import createIsValid from './selectors/isValid' +import createIsSubmitting from './selectors/isSubmitting' +import createHasSubmitSucceeded from './selectors/hasSubmitSucceeded' +import createHasSubmitFailed from './selectors/hasSubmitFailed' import FormSection from './FormSection' import SubmissionError from './SubmissionError' import propTypes from './propTypes' @@ -34,6 +37,9 @@ const createAll = structure => ({ isInvalid: createIsInvalid(structure), isPristine: createIsPristine(structure), isValid: createIsValid(structure), + isSubmitting: createIsSubmitting(structure), + hasSubmitSucceeded: createHasSubmitSucceeded(structure), + hasSubmitFailed: createHasSubmitFailed(structure), propTypes, reduxForm: createReduxForm(structure), reducer: createReducer(structure), diff --git a/src/immutable.js b/src/immutable.js index e2b0954a4..731c329a3 100644 --- a/src/immutable.js +++ b/src/immutable.js @@ -29,6 +29,9 @@ export const { isInvalid, isPristine, isValid, + isSubmitting, + hasSubmitSucceeded, + hasSubmitFailed, propTypes, reducer, reduxForm, diff --git a/src/index.js b/src/index.js index ecd63c7d1..d673815b7 100644 --- a/src/index.js +++ b/src/index.js @@ -31,6 +31,9 @@ export const { isInvalid, isPristine, isValid, + isSubmitting, + hasSubmitSucceeded, + hasSubmitFailed, propTypes, reducer, reduxForm, diff --git a/src/selectors/__tests__/hasSubmitFailed.spec.js b/src/selectors/__tests__/hasSubmitFailed.spec.js new file mode 100644 index 000000000..32a00e4aa --- /dev/null +++ b/src/selectors/__tests__/hasSubmitFailed.spec.js @@ -0,0 +1,47 @@ +import createHasSubmitFailed from '../hasSubmitFailed' +import plain from '../../structure/plain' +import plainExpectations from '../../structure/plain/expectations' +import immutable from '../../structure/immutable' +import immutableExpectations from '../../structure/immutable/expectations' +import addExpectations from '../../__tests__/addExpectations' + +const describeHasSubmitFailed = (name, structure, expect) => { + const hasSubmitFailed = createHasSubmitFailed(structure) + + const { fromJS, getIn } = structure + + describe(name, () => { + it('should return a function XXX', () => { + expect(hasSubmitFailed('foo')).toBeA('function') + }) + + it('should return false when value not present', () => { + expect(hasSubmitFailed('foo')(fromJS({ + form: {} + }))).toBe(false) + }) + + it('should return true when submitting', () => { + expect(hasSubmitFailed('foo')(fromJS({ + form: { + foo: { + submitFailed: true + } + } + }))).toBe(true) + }) + + it('should use getFormState if provided', () => { + expect(hasSubmitFailed('foo', state => getIn(state, 'someOtherSlice'))(fromJS({ + someOtherSlice: { + foo: { + submitFailed: true + } + } + }))).toBe(true) + }) + }) +} + +describeHasSubmitFailed('hasSubmitFailed.plain', plain, addExpectations(plainExpectations)) +describeHasSubmitFailed('hasSubmitFailed.immutable', immutable, addExpectations(immutableExpectations)) diff --git a/src/selectors/__tests__/hasSubmitSucceeded.spec.js b/src/selectors/__tests__/hasSubmitSucceeded.spec.js new file mode 100644 index 000000000..398abdd67 --- /dev/null +++ b/src/selectors/__tests__/hasSubmitSucceeded.spec.js @@ -0,0 +1,47 @@ +import createHasSubmitSucceeded from '../hasSubmitSucceeded' +import plain from '../../structure/plain' +import plainExpectations from '../../structure/plain/expectations' +import immutable from '../../structure/immutable' +import immutableExpectations from '../../structure/immutable/expectations' +import addExpectations from '../../__tests__/addExpectations' + +const describeHasSubmitSucceeded = (name, structure, expect) => { + const hasSubmitSucceeded = createHasSubmitSucceeded(structure) + + const { fromJS, getIn } = structure + + describe(name, () => { + it('should return a function XXX', () => { + expect(hasSubmitSucceeded('foo')).toBeA('function') + }) + + it('should return false when value not present', () => { + expect(hasSubmitSucceeded('foo')(fromJS({ + form: {} + }))).toBe(false) + }) + + it('should return true when submitting', () => { + expect(hasSubmitSucceeded('foo')(fromJS({ + form: { + foo: { + submitSucceeded: true + } + } + }))).toBe(true) + }) + + it('should use getFormState if provided', () => { + expect(hasSubmitSucceeded('foo', state => getIn(state, 'someOtherSlice'))(fromJS({ + someOtherSlice: { + foo: { + submitSucceeded: true + } + } + }))).toBe(true) + }) + }) +} + +describeHasSubmitSucceeded('hasSubmitSucceeded.plain', plain, addExpectations(plainExpectations)) +describeHasSubmitSucceeded('hasSubmitSucceeded.immutable', immutable, addExpectations(immutableExpectations)) diff --git a/src/selectors/__tests__/isSubmitting.spec.js b/src/selectors/__tests__/isSubmitting.spec.js new file mode 100644 index 000000000..3b6237035 --- /dev/null +++ b/src/selectors/__tests__/isSubmitting.spec.js @@ -0,0 +1,47 @@ +import createIsSubmitting from '../isSubmitting' +import plain from '../../structure/plain' +import plainExpectations from '../../structure/plain/expectations' +import immutable from '../../structure/immutable' +import immutableExpectations from '../../structure/immutable/expectations' +import addExpectations from '../../__tests__/addExpectations' + +const describeIsSubmitting = (name, structure, expect) => { + const isSubmitting = createIsSubmitting(structure) + + const { fromJS, getIn } = structure + + describe(name, () => { + it('should return a function XXX', () => { + expect(isSubmitting('foo')).toBeA('function') + }) + + it('should return false when value not present', () => { + expect(isSubmitting('foo')(fromJS({ + form: {} + }))).toBe(false) + }) + + it('should return true when submitting', () => { + expect(isSubmitting('foo')(fromJS({ + form: { + foo: { + submitting: true + } + } + }))).toBe(true) + }) + + it('should use getFormState if provided', () => { + expect(isSubmitting('foo', state => getIn(state, 'someOtherSlice'))(fromJS({ + someOtherSlice: { + foo: { + submitting: true + } + } + }))).toBe(true) + }) + }) +} + +describeIsSubmitting('isSubmitting.plain', plain, addExpectations(plainExpectations)) +describeIsSubmitting('isSubmitting.immutable', immutable, addExpectations(immutableExpectations)) diff --git a/src/selectors/hasSubmitFailed.js b/src/selectors/hasSubmitFailed.js new file mode 100644 index 000000000..c41818b66 --- /dev/null +++ b/src/selectors/hasSubmitFailed.js @@ -0,0 +1,8 @@ +const createHasSubmitFailed = ({ getIn }) => + (form, getFormState = state => getIn(state, 'form')) => + state => { + const formState = getFormState(state) + return getIn(formState, `${form}.submitFailed`) || false + } + +export default createHasSubmitFailed diff --git a/src/selectors/hasSubmitSucceeded.js b/src/selectors/hasSubmitSucceeded.js new file mode 100644 index 000000000..78a47e003 --- /dev/null +++ b/src/selectors/hasSubmitSucceeded.js @@ -0,0 +1,8 @@ +const createHasSubmitSucceeded = ({ getIn }) => + (form, getFormState = state => getIn(state, 'form')) => + state => { + const formState = getFormState(state) + return getIn(formState, `${form}.submitSucceeded`) || false + } + +export default createHasSubmitSucceeded diff --git a/src/selectors/isSubmitting.js b/src/selectors/isSubmitting.js new file mode 100644 index 000000000..713e9e825 --- /dev/null +++ b/src/selectors/isSubmitting.js @@ -0,0 +1,8 @@ +const createIsSubmitting = ({ getIn }) => + (form, getFormState = state => getIn(state, 'form')) => + state => { + const formState = getFormState(state) + return getIn(formState, `${form}.submitting`) || false + } + +export default createIsSubmitting From ce8c537f2628fcc43c6c13217f4e6f691a763241 Mon Sep 17 00:00:00 2001 From: dpwrussell Date: Wed, 14 Dec 2016 15:52:01 -0500 Subject: [PATCH 2/2] Add documentation for submit selectors --- docs/api/Selectors.md | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/docs/api/Selectors.md b/docs/api/Selectors.md index 8618066c7..2babadd7d 100644 --- a/docs/api/Selectors.md +++ b/docs/api/Selectors.md @@ -17,7 +17,10 @@ import { isDirty, isPristine, isValid, - isInvalid + isInvalid, + isSubmitting, + hasSubmitSucceeded, + hasSubmitFailed } from 'redux-form' MyComponent = connect( @@ -28,7 +31,10 @@ MyComponent = connect( dirty: isDirty('myForm')(state), pristine: isPristine('myForm')(state), valid: isValid('myForm')(state), - invalid: isInvalid('myForm')(state) + invalid: isInvalid('myForm')(state), + submitting: isSubmitting('myForm')(state), + submitSucceeded: hasSubmitSucceeded('myForm')(state), + submitFailed: hasSubmitFailed('myForm')(state) }) )(MyComponent) ``` @@ -66,3 +72,15 @@ of `isInvalid`. > Returns `true` if the form is invalid, i.e. has sync, async, or submission errors. The opposite of `isValid`. + +### `isSubmitting(formName:String)` returns `(state) => submitting:boolean` + +> Returns `true` if the form is submitting. + +### `hasSubmitSucceeded(formName:String)` returns `(state) => submitSucceeded:boolean` + +> Returns `true` if the form has previously been successfully submitted. + +### `hasSubmitFailed(formName:String)` returns `(state) => submitFailed:boolean` + +> Returns `true` if the form has previously failed to submit.