mirror of
https://github.com/vale981/Vulcan
synced 2025-03-05 17:41:43 -05:00
working on demo; extracting forms logic into package
This commit is contained in:
parent
f9c0faba89
commit
5b8c8d92a9
16 changed files with 56 additions and 404 deletions
|
@ -143,6 +143,7 @@ twitter@1.1.6-beta.11
|
||||||
ui@1.0.8
|
ui@1.0.8
|
||||||
underscore@1.0.5-beta.11
|
underscore@1.0.5-beta.11
|
||||||
url@1.0.6-beta.11
|
url@1.0.6-beta.11
|
||||||
|
utilities:react-form-containers@0.1.0
|
||||||
utilities:react-list-container@0.1.0
|
utilities:react-list-container@0.1.0
|
||||||
utilities:smart-methods@0.1.0
|
utilities:smart-methods@0.1.0
|
||||||
utilities:smart-publications@0.1.1
|
utilities:smart-publications@0.1.1
|
||||||
|
|
|
@ -55,4 +55,8 @@ body{
|
||||||
.comment-body{
|
.comment-body{
|
||||||
border: 1px solid #ddd;
|
border: 1px solid #ddd;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.new-post-button{
|
||||||
|
margin-bottom: 15px;
|
||||||
}
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
import SmartContainers from "meteor/utilities:react-list-container";
|
import SmartContainers from "meteor/utilities:react-list-container";
|
||||||
|
import FormContainers from "meteor/utilities:react-form-containers";
|
||||||
|
|
||||||
Telescope.registerComponent("AppContainer", require('./containers/AppContainer.jsx'));
|
Telescope.registerComponent("AppContainer", require('./containers/AppContainer.jsx'));
|
||||||
// Telescope.registerComponent("ItemContainer", require('./containers/ItemContainer.jsx'));
|
// Telescope.registerComponent("ItemContainer", require('./containers/ItemContainer.jsx'));
|
||||||
|
@ -12,7 +13,11 @@ Telescope.registerComponent("ListContainer", SmartContainers.ListContainer);
|
||||||
|
|
||||||
Telescope.registerComponent("FlashContainer", require('./containers/FlashContainer.jsx'));
|
Telescope.registerComponent("FlashContainer", require('./containers/FlashContainer.jsx'));
|
||||||
Telescope.registerComponent("CurrentUserContainer", require('./containers/CurrentUserContainer.jsx'));
|
Telescope.registerComponent("CurrentUserContainer", require('./containers/CurrentUserContainer.jsx'));
|
||||||
Telescope.registerComponent("NewDocContainer", require('./containers/NewDocContainer.jsx'));
|
|
||||||
Telescope.registerComponent("EditDocContainer", require('./containers/EditDocContainer.jsx'));
|
// Telescope.registerComponent("NewDocContainer", require('./containers/NewDocContainer.jsx'));
|
||||||
|
// Telescope.registerComponent("EditDocContainer", require('./containers/EditDocContainer.jsx'));
|
||||||
|
|
||||||
|
Telescope.registerComponent("NewDocContainer", FormContainers.NewDocContainer);
|
||||||
|
Telescope.registerComponent("EditDocContainer", FormContainers.EditDocContainer);
|
||||||
|
|
||||||
Telescope.registerComponent("ModalButton", require('./components/ModalButton.jsx'));
|
Telescope.registerComponent("ModalButton", require('./components/ModalButton.jsx'));
|
||||||
|
|
|
@ -51,7 +51,7 @@ const ModalButton = React.createClass({
|
||||||
callback = this.closeModal;
|
callback = this.closeModal;
|
||||||
}
|
}
|
||||||
|
|
||||||
return React.cloneElement(child, { callback: callback });
|
return React.cloneElement(child, { successCallback: callback });
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -71,4 +71,5 @@ const ModalButton = React.createClass({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = ModalButton;
|
module.exports = ModalButton;
|
||||||
|
export default ModalButton;
|
|
@ -34,4 +34,5 @@ const AppContainer = React.createClass({
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = AppContainer;
|
module.exports = AppContainer;
|
||||||
|
export default AppContainer;
|
|
@ -15,4 +15,5 @@ const CurrentUserContainer = React.createClass({
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = CurrentUserContainer;
|
module.exports = CurrentUserContainer;
|
||||||
|
export default CurrentUserContainer;
|
|
@ -1,63 +0,0 @@
|
||||||
import Messages from "../messages.js";
|
|
||||||
import NovaForms from "../forms.jsx";
|
|
||||||
|
|
||||||
import Formsy from 'formsy-react';
|
|
||||||
|
|
||||||
const EditDocContainer = React.createClass({
|
|
||||||
|
|
||||||
propTypes: {
|
|
||||||
document: React.PropTypes.object, // required but might be passed later on
|
|
||||||
collection: React.PropTypes.object, // required but might be passed later on
|
|
||||||
label: React.PropTypes.string,
|
|
||||||
callback: React.PropTypes.func,
|
|
||||||
methodName: React.PropTypes.string
|
|
||||||
},
|
|
||||||
|
|
||||||
mixins: [ReactMeteorData],
|
|
||||||
|
|
||||||
getMeteorData() {
|
|
||||||
console.log(this)
|
|
||||||
|
|
||||||
return {
|
|
||||||
currentUser: Meteor.user()
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
submitForm(data) {
|
|
||||||
const document = this.props.document;
|
|
||||||
const modifier = {$set: _.compactObject(data)};
|
|
||||||
const collection = this.props.collection;
|
|
||||||
const methodName = this.props.methodName ? this.props.methodName : collection._name+'.edit';
|
|
||||||
|
|
||||||
Meteor.call(methodName, document._id, modifier, (error, document) => {
|
|
||||||
if (error) {
|
|
||||||
console.log(error)
|
|
||||||
Messages.flash(error.message, "error")
|
|
||||||
} else {
|
|
||||||
Messages.flash("Document edited.", "success");
|
|
||||||
if (this.props.callback) {
|
|
||||||
this.props.callback(document);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
render() {
|
|
||||||
|
|
||||||
const document = this.props.document;
|
|
||||||
const collection = this.props.collection;
|
|
||||||
const fields = collection.getInsertableFields(this.data.currentUser);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="document-edit">
|
|
||||||
<h3>{this.props.label}</h3>
|
|
||||||
<Formsy.Form onSubmit={this.submitForm}>
|
|
||||||
{fields.map(fieldName => NovaForms.getComponent(fieldName, collection.simpleSchema()._schema[fieldName], document))}
|
|
||||||
<button type="submit" className="button button--primary">Submit</button>
|
|
||||||
</Formsy.Form>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
module.exports = EditDocContainer;
|
|
|
@ -24,4 +24,5 @@ const FlashContainer = React.createClass({
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = FlashContainer;
|
module.exports = FlashContainer;
|
||||||
|
export default FlashContainer;
|
|
@ -1,61 +0,0 @@
|
||||||
// const ItemContainer = React.createClass({
|
|
||||||
|
|
||||||
// propTypes: {
|
|
||||||
// collection: React.PropTypes.object.isRequired,
|
|
||||||
// selector: React.PropTypes.object.isRequired,
|
|
||||||
// publication: React.PropTypes.string,
|
|
||||||
// joins: React.PropTypes.array,
|
|
||||||
// loading: React.PropTypes.func
|
|
||||||
// },
|
|
||||||
|
|
||||||
// mixins: [ReactMeteorData],
|
|
||||||
|
|
||||||
// getMeteorData() {
|
|
||||||
|
|
||||||
// // subscribe if necessary
|
|
||||||
// if (this.props.publication) {
|
|
||||||
// const subscription = Meteor.subscribe(this.props.publication, this.props.selector);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// const collection = this.props.collection;
|
|
||||||
// const document = collection.findOne(this.props.selector);
|
|
||||||
|
|
||||||
// // look for any specified joins
|
|
||||||
// if (document && this.props.joins) {
|
|
||||||
|
|
||||||
// // loop over each join
|
|
||||||
// this.props.joins.forEach(join => {
|
|
||||||
|
|
||||||
// // get the property containing the id or ids
|
|
||||||
// const joinProperty = document[join.property];
|
|
||||||
// const collection = Meteor.isClient ? window[join.collection] : global[join.collection];
|
|
||||||
|
|
||||||
// // perform the join
|
|
||||||
// if (Array.isArray(joinProperty)) { // join property is an array of ids
|
|
||||||
// document[join.joinAs] = collection.find({_id: {$in: joinProperty}}).fetch();
|
|
||||||
// } else { // join property is a single id
|
|
||||||
// document[join.joinAs] = collection.findOne({_id: joinProperty});
|
|
||||||
// }
|
|
||||||
|
|
||||||
// });
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return {
|
|
||||||
// document: document,
|
|
||||||
// currentUser: Meteor.user()
|
|
||||||
// };
|
|
||||||
// },
|
|
||||||
|
|
||||||
// render() {
|
|
||||||
// const loadingComponent = this.props.loading ? this.props.loading : <p>Loading…</p>
|
|
||||||
// if (this.data.document) {
|
|
||||||
// return React.cloneElement(this.props.children, { ...this.data, collection: this.props.collection });
|
|
||||||
// } else {
|
|
||||||
// return loadingComponent;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// });
|
|
||||||
|
|
||||||
// module.exports = ItemContainer;
|
|
|
@ -1,144 +0,0 @@
|
||||||
// /*
|
|
||||||
// Example code:
|
|
||||||
|
|
||||||
// <ListContainer
|
|
||||||
// collection={Posts}
|
|
||||||
// publication="posts.list"
|
|
||||||
// terms={queryParams}
|
|
||||||
// component={PostList}
|
|
||||||
// joins={[
|
|
||||||
// {
|
|
||||||
// property: "categories",
|
|
||||||
// joinAs: "categoriesArray",
|
|
||||||
// collection: "Categories"
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// property: "userId",
|
|
||||||
// joinAs: "user",
|
|
||||||
// collection: "Users"
|
|
||||||
// }
|
|
||||||
// ]}
|
|
||||||
// />
|
|
||||||
|
|
||||||
// Note that the joins are client-side only, and expect you to
|
|
||||||
// make the relevant data available separately.
|
|
||||||
|
|
||||||
// */
|
|
||||||
|
|
||||||
// const ListContainer = React.createClass({
|
|
||||||
|
|
||||||
// propTypes: {
|
|
||||||
// collection: React.PropTypes.object.isRequired, // the collection to paginate
|
|
||||||
// selector: React.PropTypes.object, // the selector used in collection.find()
|
|
||||||
// options: React.PropTypes.object, // the options used in collection.find()
|
|
||||||
// publication: React.PropTypes.string, // the publication to subscribe to
|
|
||||||
// terms: React.PropTypes.object, // an object passed to the publication
|
|
||||||
// limit: React.PropTypes.number, // the limit used to increase pagination
|
|
||||||
// joins: React.PropTypes.array, // joins to apply to the results
|
|
||||||
// parentProperty: React.PropTypes.string // if provided, use to generate tree
|
|
||||||
// },
|
|
||||||
|
|
||||||
// getDefaultProps: function() {
|
|
||||||
// return {
|
|
||||||
// limit: 5
|
|
||||||
// };
|
|
||||||
// },
|
|
||||||
|
|
||||||
// getInitialState() {
|
|
||||||
// return {
|
|
||||||
// limit: this.props.limit
|
|
||||||
// };
|
|
||||||
// },
|
|
||||||
|
|
||||||
// mixins: [ReactMeteorData],
|
|
||||||
|
|
||||||
// getMeteorData() {
|
|
||||||
|
|
||||||
// // initialize data object with current user, and default to data being ready
|
|
||||||
// let data = {
|
|
||||||
// currentUser: Meteor.user(),
|
|
||||||
// ready: true
|
|
||||||
// };
|
|
||||||
|
|
||||||
// // subscribe if needed. Note: always subscribe first, otherwise
|
|
||||||
// // it won't work when server-side rendering with FlowRouter SSR
|
|
||||||
// if (this.props.publication) {
|
|
||||||
// let terms = {...this.props.terms, limit: this.state.limit};
|
|
||||||
// const subscription = Meteor.subscribe(this.props.publication, terms);
|
|
||||||
// data.ready = subscription.ready();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// const selector = this.props.selector || {};
|
|
||||||
// const options = {...this.props.options, limit: this.state.limit};
|
|
||||||
|
|
||||||
// const cursor = this.props.collection.find(selector, options);
|
|
||||||
// const count = cursor.count();
|
|
||||||
// // when rendering on the server, we want to get a count without the limit
|
|
||||||
// const optionsNoLimit = {...this.props.options, limit: 0};
|
|
||||||
// const cursorNoLimit = this.props.collection.find(selector, optionsNoLimit);
|
|
||||||
|
|
||||||
// const totalCount = Meteor.isClient ? Counts.get(this.props.publication) : cursorNoLimit.count();
|
|
||||||
|
|
||||||
// let results = cursor.fetch();
|
|
||||||
|
|
||||||
// // look for any specified joins
|
|
||||||
// if (this.props.joins) {
|
|
||||||
|
|
||||||
// // loop over each document in the results
|
|
||||||
// results.forEach(doc => {
|
|
||||||
|
|
||||||
// // loop over each join
|
|
||||||
// this.props.joins.forEach(join => {
|
|
||||||
|
|
||||||
// // get the property containing the id or ids
|
|
||||||
// const joinProperty = doc[join.property];
|
|
||||||
// const collection = join.collection();
|
|
||||||
// const joinLimit = join.limit ? join.limit : 0;
|
|
||||||
|
|
||||||
// // perform the join
|
|
||||||
// if (Array.isArray(joinProperty)) { // join property is an array of ids
|
|
||||||
// doc[join.joinAs] = collection.find({_id: {$in: joinProperty}}, {limit: joinLimit}).fetch();
|
|
||||||
// } else { // join property is a single id
|
|
||||||
// doc[join.joinAs] = collection.findOne({_id: joinProperty});
|
|
||||||
// }
|
|
||||||
|
|
||||||
// });
|
|
||||||
|
|
||||||
// // return the updated document
|
|
||||||
// return doc;
|
|
||||||
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // transform list into tree
|
|
||||||
// if (this.props.parentProperty) {
|
|
||||||
// results = Telescope.utils.unflatten(results, "_id", this.props.parentProperty);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// data = {
|
|
||||||
// ...data,
|
|
||||||
// results: results,
|
|
||||||
// count: count,
|
|
||||||
// totalCount: totalCount,
|
|
||||||
// hasMore: count < totalCount
|
|
||||||
// };
|
|
||||||
|
|
||||||
// return data;
|
|
||||||
// },
|
|
||||||
|
|
||||||
// loadMore(event) {
|
|
||||||
// event.preventDefault();
|
|
||||||
// this.setState({
|
|
||||||
// limit: this.state.limit+this.props.limit
|
|
||||||
// });
|
|
||||||
// },
|
|
||||||
|
|
||||||
// render() {
|
|
||||||
// return React.cloneElement(this.props.children, { ...this.data, loadMore: this.loadMore});
|
|
||||||
// }
|
|
||||||
|
|
||||||
// });
|
|
||||||
|
|
||||||
// // export default PostListContainer;
|
|
||||||
|
|
||||||
// module.exports = ListContainer;
|
|
|
@ -1,59 +0,0 @@
|
||||||
import Messages from "../messages.js";
|
|
||||||
import NovaForms from "../forms.jsx";
|
|
||||||
|
|
||||||
import Formsy from 'formsy-react';
|
|
||||||
|
|
||||||
const NewDocContainer = React.createClass({
|
|
||||||
|
|
||||||
propTypes: {
|
|
||||||
collection: React.PropTypes.object.isRequired,
|
|
||||||
label: React.PropTypes.string,
|
|
||||||
callback: React.PropTypes.func,
|
|
||||||
methodName: React.PropTypes.string
|
|
||||||
},
|
|
||||||
|
|
||||||
mixins: [ReactMeteorData],
|
|
||||||
|
|
||||||
getMeteorData() {
|
|
||||||
return {
|
|
||||||
currentUser: Meteor.user()
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
submitForm(data) {
|
|
||||||
// remove any empty properties
|
|
||||||
const document = _.compactObject(data);
|
|
||||||
const collection = this.props.collection;
|
|
||||||
const methodName = this.props.methodName ? this.props.methodName : collection._name+'.create';
|
|
||||||
|
|
||||||
Meteor.call(methodName, document, (error, document) => {
|
|
||||||
if (error) {
|
|
||||||
console.log(error)
|
|
||||||
Messages.flash(error.message, "error")
|
|
||||||
} else {
|
|
||||||
Messages.flash("Document created.", "success");
|
|
||||||
if (this.props.callback) {
|
|
||||||
this.props.callback(document);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
render() {
|
|
||||||
|
|
||||||
const collection = this.props.collection;
|
|
||||||
const fields = collection.getInsertableFields(this.data.currentUser);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="new-document">
|
|
||||||
<h3>{this.props.label}</h3>
|
|
||||||
<Formsy.Form onSubmit={this.submitForm}>
|
|
||||||
{fields.map(fieldName => NovaForms.getComponent(fieldName, collection.simpleSchema()._schema[fieldName]))}
|
|
||||||
<button type="submit" className="button button--primary">Submit</button>
|
|
||||||
</Formsy.Form>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
module.exports = NewDocContainer;
|
|
|
@ -1,4 +1,7 @@
|
||||||
import Messages from "./messages.js";
|
import Messages from "./messages.js";
|
||||||
import NovaForms from "./forms.jsx";
|
|
||||||
|
|
||||||
export default {Messages, NovaForms};
|
import FlashContainer from "./containers/FlashContainer.jsx";
|
||||||
|
|
||||||
|
import ModalButton from "./components/ModalButton.jsx";
|
||||||
|
|
||||||
|
export default {Messages, FlashContainer, ModalButton};
|
|
@ -1,41 +0,0 @@
|
||||||
import Formsy from 'formsy-react';
|
|
||||||
import FRC from 'formsy-react-components';
|
|
||||||
|
|
||||||
const Checkbox = FRC.Checkbox;
|
|
||||||
const CheckboxGroup = FRC.CheckboxGroup;
|
|
||||||
const Input = FRC.Input;
|
|
||||||
const RadioGroup = FRC.RadioGroup;
|
|
||||||
const Select = FRC.Select;
|
|
||||||
const Textarea = FRC.Textarea;
|
|
||||||
|
|
||||||
const NovaForms = {};
|
|
||||||
|
|
||||||
NovaForms.getComponent = (fieldName, field, document) => {
|
|
||||||
|
|
||||||
let options = [];
|
|
||||||
if (field.autoform && field.autoform.options) {
|
|
||||||
options = typeof field.autoform.options === "function" ? field.autoform.options() : field.autoform.options;
|
|
||||||
}
|
|
||||||
|
|
||||||
const value = document && document[fieldName] ? document[fieldName] : "";
|
|
||||||
|
|
||||||
switch (field.control) {
|
|
||||||
|
|
||||||
case "text":
|
|
||||||
return <Input key={fieldName} name={fieldName} value={value} label={fieldName} type="text" className="text-input"/>;
|
|
||||||
case "textarea":
|
|
||||||
return <Textarea key={fieldName} name={fieldName} value={value} label={fieldName} className="textarea"/>;
|
|
||||||
case "checkbox":
|
|
||||||
return <Checkbox key={fieldName} name={fieldName} value={value} label={fieldName}/>;
|
|
||||||
case "checkboxgroup":
|
|
||||||
return <CheckboxGroup key={fieldName} name={fieldName} value={value} label={fieldName} options={options} />;
|
|
||||||
case "radiogroup":
|
|
||||||
return <RadioGroup key={fieldName} name={fieldName} value={value} label={fieldName} options={options} />;
|
|
||||||
case "select":
|
|
||||||
return <Select key={fieldName} name={fieldName} value={value} label={fieldName} options={options} />;
|
|
||||||
default:
|
|
||||||
return <Input key={fieldName} name={fieldName} value={value} label={fieldName} type="text" className="text-input"/>;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default NovaForms;
|
|
|
@ -15,7 +15,8 @@ Package.onUse(function(api) {
|
||||||
'nova:i18n@0.25.7', // lib
|
'nova:i18n@0.25.7', // lib
|
||||||
'nova:events@0.25.7', // lib, i18n
|
'nova:events@0.25.7', // lib, i18n
|
||||||
'nova:settings@0.25.7', // lib, i18n
|
'nova:settings@0.25.7', // lib, i18n
|
||||||
'utilities:react-list-container'
|
'utilities:react-list-container',
|
||||||
|
'utilities:react-form-containers'
|
||||||
];
|
];
|
||||||
|
|
||||||
api.use(packages);
|
api.use(packages);
|
||||||
|
|
|
@ -1,16 +1,5 @@
|
||||||
import {mount} from 'react-mounter';
|
import {mount} from 'react-mounter';
|
||||||
|
|
||||||
//////////////////////////////////////////////////////
|
|
||||||
// Route //
|
|
||||||
//////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
FlowRouter.route('/demo', {
|
|
||||||
name: 'demo',
|
|
||||||
action(params, queryParams) {
|
|
||||||
mount(MoviesWrapper);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////
|
||||||
// Collection & Schema //
|
// Collection & Schema //
|
||||||
//////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////
|
||||||
|
@ -18,7 +7,7 @@ FlowRouter.route('/demo', {
|
||||||
Movies = new Mongo.Collection("movies");
|
Movies = new Mongo.Collection("movies");
|
||||||
|
|
||||||
const isLoggedIn = user => !!user;
|
const isLoggedIn = user => !!user;
|
||||||
const isOwner = (user, document) => {user._id === document.userId};
|
const isOwner = (user, document) => user._id === document.userId;
|
||||||
|
|
||||||
const schema = new SimpleSchema({
|
const schema = new SimpleSchema({
|
||||||
name: {
|
name: {
|
||||||
|
@ -60,12 +49,23 @@ const schema = new SimpleSchema({
|
||||||
|
|
||||||
Movies.attachSchema(schema);
|
Movies.attachSchema(schema);
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////
|
||||||
|
// Route //
|
||||||
|
//////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
FlowRouter.route('/demo', {
|
||||||
|
name: 'demo',
|
||||||
|
action() {
|
||||||
|
mount(MoviesWrapper);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
//////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////
|
||||||
// Methods //
|
// Methods //
|
||||||
//////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////
|
||||||
|
|
||||||
Movies.smartMethods({
|
Movies.smartMethods({
|
||||||
createCallback: function (document) {
|
createCallback: function (user, document) {
|
||||||
document = _.extend(document, {
|
document = _.extend(document, {
|
||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
userId: Meteor.userId()
|
userId: Meteor.userId()
|
||||||
|
|
|
@ -1,5 +1,15 @@
|
||||||
import NoSSR from 'react-no-ssr';
|
import NoSSR from 'react-no-ssr';
|
||||||
|
|
||||||
|
import Core from 'meteor/nova:core';
|
||||||
|
import SmartContainers from "meteor/utilities:react-list-container";
|
||||||
|
import FormContainers from "meteor/utilities:react-form-containers";
|
||||||
|
|
||||||
|
FlashContainer = Core.FlashContainer;
|
||||||
|
ModalButton = Core.ModalButton;
|
||||||
|
NewDocContainer = FormContainers.NewDocContainer;
|
||||||
|
EditDocContainer = FormContainers.EditDocContainer;
|
||||||
|
ListContainer = SmartContainers.ListContainer;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////
|
||||||
// MoviesWrapper //
|
// MoviesWrapper //
|
||||||
//////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////
|
||||||
|
@ -8,10 +18,8 @@ MoviesWrapper = React.createClass({
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
||||||
({ListContainer, FlashContainer} = Telescope.components);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className="wrapper">
|
||||||
|
|
||||||
<NoSSR onSSR={<p>Loading…</p>}>
|
<NoSSR onSSR={<p>Loading…</p>}>
|
||||||
<LogInButtons />
|
<LogInButtons />
|
||||||
|
@ -26,7 +34,6 @@ MoviesWrapper = React.createClass({
|
||||||
terms={{options: {sort: {createdAt: -1}}}}
|
terms={{options: {sort: {createdAt: -1}}}}
|
||||||
options={{sort: {createdAt: -1}}}
|
options={{sort: {createdAt: -1}}}
|
||||||
joins={Movies.getJoins()}
|
joins={Movies.getJoins()}
|
||||||
limit={4}
|
|
||||||
>
|
>
|
||||||
<MoviesList/>
|
<MoviesList/>
|
||||||
</ListContainer>
|
</ListContainer>
|
||||||
|
@ -35,7 +42,7 @@ MoviesWrapper = React.createClass({
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
//////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////
|
||||||
// MoviesList //
|
// MoviesList //
|
||||||
|
@ -45,8 +52,6 @@ MoviesList = React.createClass({
|
||||||
|
|
||||||
renderNew() {
|
renderNew() {
|
||||||
|
|
||||||
({ModalButton, NewDocContainer} = Telescope.components);
|
|
||||||
|
|
||||||
const component = (
|
const component = (
|
||||||
<ModalButton label="Add Movie" className="button button--primary">
|
<ModalButton label="Add Movie" className="button button--primary">
|
||||||
<NewDocContainer collection={Movies} label="Add Movie" methodName="movies.create"/>
|
<NewDocContainer collection={Movies} label="Add Movie" methodName="movies.create"/>
|
||||||
|
@ -57,7 +62,6 @@ MoviesList = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
({LoadMore} = Telescope.components);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="movies">
|
<div className="movies">
|
||||||
|
@ -68,18 +72,14 @@ MoviesList = React.createClass({
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////
|
||||||
// Movie //
|
// Movie //
|
||||||
//////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////
|
||||||
|
|
||||||
Movie = React.createClass({
|
Movie = React.createClass({
|
||||||
|
|
||||||
|
|
||||||
renderEdit() {
|
renderEdit() {
|
||||||
|
|
||||||
({ModalButton, EditDocContainer} = Telescope.components);
|
|
||||||
|
|
||||||
const movie = this.props;
|
const movie = this.props;
|
||||||
|
|
||||||
const component = (
|
const component = (
|
||||||
|
@ -108,4 +108,6 @@ Movie = React.createClass({
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const LoadMore = props => <a href="#" className="load-more button button--primary" onClick={props.loadMore}>Load More ({props.count}/{props.totalCount})</a>
|
Loading…
Add table
Reference in a new issue