Skip to content

Commit

Permalink
Merge pull request #431 from codaco/feature/inline-forms
Browse files Browse the repository at this point in the history
Edit forms inline
  • Loading branch information
wwqrd authored Mar 27, 2019
2 parents 08fdf11 + 2d3eeb6 commit 814ff9c
Show file tree
Hide file tree
Showing 112 changed files with 1,303 additions and 909 deletions.
2 changes: 1 addition & 1 deletion public/template/protocol.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "",
"variableRegistry": {
"codebook": {
"node": {},
"edge": {}
},
Expand Down
26 changes: 26 additions & 0 deletions src/components/Badge.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from 'react';
import PropTypes from 'prop-types';

const Badge = ({ color, children }) => {
const style = color ?
{ backgroundColor: color } :
{};

return (
<div className="badge" style={style}>
{children}
</div>
);
};

Badge.propTypes = {
color: PropTypes.string,
children: PropTypes.node,
};

Badge.defaultProps = {
color: null,
children: null,
};

export default Badge;
102 changes: 54 additions & 48 deletions src/components/EditableList/EditableList.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ import {
} from 'recompose';
import { Flipper, Flipped } from 'react-flip-toolkit';
import PropTypes from 'prop-types';
import cx from 'classnames';
import { getFieldId, scrollToFirstIssue } from '../../utils/issues';
import Guidance from '../Guidance';
import OrderedList, { NewButton } from '../OrderedList';
import UnorderedList from '../UnorderedList';
import ValidatedFieldArray from '../Form/ValidatedFieldArray';
import Section from '../sections/Section'; // Should this exist out of sections if it's used here?
import Window from './Window';
import Form, { formName } from './Form';
import withEditHandlers from './withEditHandlers';
Expand Down Expand Up @@ -44,6 +44,7 @@ class EditableList extends PureComponent {
children,
upsert,
title,
validation,
itemCount,
setEditField,
initialValues,
Expand All @@ -52,59 +53,62 @@ class EditableList extends PureComponent {
...rest
} = this.props;

const stageEditorStyles = cx(
'stage-editor-section',
{ 'stage-editor-section--disabled': disabled },
);

const isEditing = !!editField;

const ListComponent = sortMode !== 'manual' ? UnorderedList : OrderedList;

const editableListSection = (
<Section disabled={disabled}>
<Flipper
flipKey={isEditing}
portalKey="editable-list"
>
<div id={getFieldId(`${fieldName}._error`)} data-name={fieldName} />
{children}
<div className="editable-list">
<div className="editable-list__items">
<ValidatedFieldArray
name={fieldName}
component={ListComponent}
item={PreviewComponent}
validation={validation}
onClickPrompt={handleEditField}
editField={editField}
{...rest}
/>
</div>
<Flipped flipId={null}>
<NewButton onClick={handleAddNew} />
</Flipped>
</div>
<Window show={!!editField}>
<Form
initialValues={initialValues}
flipId={editField}
title={title}
onSubmit={handleUpdate}
onSubmitFail={handleSubmitFail}
onCancel={handleResetEditField}
>
<EditComponent
{...rest}
form={formName}
fieldId={editField}
onComplete={handleResetEditField}
/>
</Form>
</Window>
</Flipper>
</Section>
);

if (!contentId) {
return editableListSection;
}

return (
<Guidance contentId={contentId}>
<div className={stageEditorStyles}>
<Flipper
flipKey={isEditing}
portalKey="editable-list"
>
<div id={getFieldId(`${fieldName}._error`)} data-name={fieldName} />
{children}
<div className="editable-list">
<div className="editable-list__items">
<ValidatedFieldArray
name={fieldName}
component={ListComponent}
item={PreviewComponent}
validation={{ notEmpty }}
onClickPrompt={handleEditField}
editField={editField}
{...rest}
/>
</div>
<Flipped flipId={null}>
<NewButton onClick={handleAddNew} />
</Flipped>
</div>
<Window show={!!editField}>
<Form
initialValues={initialValues}
flipId={editField}
title={title}
onSubmit={handleUpdate}
onSubmitFail={handleSubmitFail}
onCancel={handleResetEditField}
>
<EditComponent
{...rest}
form={formName}
fieldId={editField}
onComplete={handleResetEditField}
/>
</Form>
</Window>
</Flipper>
</div>
{editableListSection}
</Guidance>
);
}
Expand All @@ -120,6 +124,7 @@ EditableList.propTypes = {
children: PropTypes.node,
previewComponent: PropTypes.any.isRequired,
editComponent: PropTypes.any.isRequired,
validation: PropTypes.object,
};

EditableList.defaultProps = {
Expand All @@ -128,6 +133,7 @@ EditableList.defaultProps = {
children: null,
title: null,
sortMode: 'manual',
validation: { notEmpty },
};

const withDefaultFieldName = defaultProps({
Expand Down
17 changes: 8 additions & 9 deletions src/components/EditableList/withEditHandlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,16 @@ import {
defaultProps,
withHandlers,
} from 'recompose';
import { get } from 'lodash';
import {
formValueSelector,
change,
} from 'redux-form';

const mapStateToProps = (state, { form, fieldName, editField, template = {} }) => {
const mapStateToProps = (state, { form, fieldName, itemSelector, editField, template }) => {
const items = formValueSelector(form)(state, fieldName);
const itemCount = items ? items.length : 0;

const initialValues = get(
{ [fieldName]: items },
editField,
{ ...template, id: uuid() },
);

const item = itemSelector(state, { form, editField });
const initialValues = item || { ...template(), id: uuid() };

return {
itemCount,
Expand Down Expand Up @@ -51,9 +45,11 @@ const handlers = withHandlers({
setEditField,
editField,
normalize,
onChange,
}) =>
(value) => {
upsert(editField, normalize(value));
if (onChange) { onChange(value); }
setImmediate(() => {
setEditField();
});
Expand All @@ -63,6 +59,9 @@ const handlers = withHandlers({
const withEditHandlers = compose(
defaultProps({
normalize: value => value,
template: () => {},
itemSelector: (state, { form, editField }) =>
formValueSelector(form)(state, editField),
}),
connect(mapStateToProps, mapDispatchToProps),
handlers,
Expand Down
29 changes: 29 additions & 0 deletions src/components/Form/FieldError.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React from 'react';
import PropTypes from 'prop-types';
import cx from 'classnames';
import Icon from '../../ui/components/Icon';

const FieldError = ({ error, show }) => {
const errorClasses = cx(
'form-field-error',
{ 'form-field-error--show': show },
);

return (
<div className={errorClasses}>
<Icon name="warning" /> { error }
</div>
);
};

FieldError.propTypes = {
error: PropTypes.string,
show: PropTypes.bool,
};

FieldError.defaultProps = {
show: false,
error: null,
};

export default FieldError;
Loading

0 comments on commit 814ff9c

Please sign in to comment.