Skip to content

Commit

Permalink
Merge pull request keystonejs#1 from njs50/release
Browse files Browse the repository at this point in the history
inline creation of related items
  • Loading branch information
cadriel authored Nov 29, 2017
2 parents 50f9c9d + 3511c21 commit 872ea4b
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import React from 'react';
import { Link } from 'react-router';
import { Alert, BlankState, Center, Spinner } from '../../../../elemental';
import { Alert, BlankState, Center, GlyphButton, ResponsiveText, Spinner } from '../../../../elemental';

import DragDrop from './RelatedItemsListDragDrop';
import ListRow from './RelatedItemsListRow';
import CreateForm from '../../../../shared/CreateForm';

import { loadRelationshipItemData } from '../../actions';
import { TABLE_CONTROL_COLUMN_WIDTH } from '../../../../../constants';

import Toolbar from '../Toolbar';
import ToolbarSection from '../Toolbar/ToolbarSection';

const RelatedItemsList = React.createClass({
propTypes: {
dispatch: React.PropTypes.func.isRequired,
Expand All @@ -18,11 +22,15 @@ const RelatedItemsList = React.createClass({
relatedItemId: React.PropTypes.string.isRequired,
relationship: React.PropTypes.object.isRequired,
},
contextTypes: {
router: React.PropTypes.object.isRequired,
},
getInitialState () {
return {
columns: this.getColumns(),
err: null,
items: null,
createIsOpen: false,
};
},
componentDidMount () {
Expand Down Expand Up @@ -116,12 +124,67 @@ const RelatedItemsList = React.createClass({

return <thead><tr>{cells}</tr></thead>;
},
renderCreateButton () {
const { singular } = this.props.refList;

const { createInline, editOnCreate, refPath } = this.props.relationship;

let defaultValues = {};
defaultValues[refPath] = this.props.relatedItemId;

if (!createInline) return null;

return (
<div>
<GlyphButton color="success" glyph="plus" position="left" onClick={() => { this.toggleCreate(true); }}>
<ResponsiveText hiddenXS={`New ${singular}`} visibleXS="Create" />
</GlyphButton>
<CreateForm
defaultValues={defaultValues}
list={this.props.refList}
isOpen={this.state.createIsOpen}
onCancel={() => this.toggleCreate(false)}
onCreate={(item) => this.onCreate(item, editOnCreate)}
/>
</div>
);
},
toggleCreate (visible) {
this.setState({
createIsOpen: visible,
});
},
onCreate (item, editOnCreate) {
this.toggleCreate(false);

if (editOnCreate) {
const list = this.props.refList;
this.context.router.push(`${Keystone.adminPath}/${list.path}/${item.id}`);
} else {
this.setState({
items: null,
});
this.loadItems();
}
},
renderRelatedTitle () {
const { path, label, hidden } = this.props.refList;

const listHref = `${Keystone.adminPath}/${path}`;

// don't render a link to the related list if it's supposed to be hidden in the Admin UI
if (hidden) {
return <h3>{label}</h3>;
}

return <h3 className="Relationship__link"><Link to={listHref}>{label}</Link></h3>;
},
render () {
if (this.state.err) {
return <div className="Relationship">{this.state.err}</div>;
}

const listHref = `${Keystone.adminPath}/${this.props.refList.path}`;

const loadingElement = (
<Center height={100}>
<Spinner />
Expand All @@ -130,7 +193,14 @@ const RelatedItemsList = React.createClass({

return (
<div className="Relationship">
<h3 className="Relationship__link"><Link to={listHref}>{this.props.refList.label}</Link></h3>
<Toolbar>
<ToolbarSection left>
{this.renderRelatedTitle()}
</ToolbarSection>
<ToolbarSection right>
{this.renderCreateButton()}
</ToolbarSection>
</Toolbar>
{this.props.items ? this.renderItems() : loadingElement}
</div>
);
Expand Down
30 changes: 25 additions & 5 deletions admin/client/App/shared/CreateForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { Button, Form, Modal } from '../elemental';
const CreateForm = React.createClass({
displayName: 'CreateForm',
propTypes: {
defaultValues: React.PropTypes.object,
err: React.PropTypes.object,
isOpen: React.PropTypes.bool,
list: React.PropTypes.object,
Expand All @@ -35,8 +36,16 @@ const CreateForm = React.createClass({
var FieldComponent = Fields[field.type];
values[field.path] = FieldComponent.getDefaultValue(field);
});

if (this.props.defaultValues) {
Object.keys(this.props.defaultValues).forEach(key => {
values[key] = this.props.defaultValues[key];
});
}

return {
values: values,
defaultValues: assign({}, values),
alerts: {},
};
},
Expand All @@ -48,7 +57,7 @@ const CreateForm = React.createClass({
},
handleKeyPress (evt) {
if (vkey[evt.keyCode] === '<escape>') {
this.props.onCancel();
this.onModalClose();
}
},
// Handle input change events
Expand All @@ -69,19 +78,30 @@ const CreateForm = React.createClass({
props.key = field.path;
return props;
},
resetForm () {
var values = assign({}, this.state.defaultValues);
this.setState({
values: values,
});
},
onModalClose () {
this.resetForm();
this.props.onCancel();
},
// Create a new item when the form is submitted
submitForm (event) {
event.preventDefault();
const createForm = event.target;
const formData = new FormData(createForm);
this.props.list.createItem(formData, (err, data) => {
if (data) {
// reset the form
this.resetForm();
if (this.props.onCreate) {
this.props.onCreate(data);
} else {
// Clear form
// set a success alert
this.setState({
values: {},
alerts: {
success: {
success: 'Item created',
Expand Down Expand Up @@ -168,7 +188,7 @@ const CreateForm = React.createClass({
variant="link"
color="cancel"
data-button-type="cancel"
onClick={this.props.onCancel}
onClick={this.onModalClose}
>
Cancel
</Button>
Expand All @@ -180,7 +200,7 @@ const CreateForm = React.createClass({
return (
<Modal.Dialog
isOpen={this.props.isOpen}
onClose={this.props.onCancel}
onClose={this.onModalClose}
backdropClosesModal
>
{this.renderForm()}
Expand Down

0 comments on commit 872ea4b

Please sign in to comment.