Skip to content

Instantly share code, notes, and snippets.

@grokbot
Last active November 10, 2015 13:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save grokbot/bf20f18952e341579965 to your computer and use it in GitHub Desktop.
Save grokbot/bf20f18952e341579965 to your computer and use it in GitHub Desktop.
React-DnD - Meteor React
UserList = React.createClass({
mixins: [ReactMeteorData],
getMeteorData() {
return {
users: Meteor.users.find().fetch()
}
},
render () {
return (
<div>
{this.renderUsers()}
</div>
);
},
renderUsers () {
return this.data.users.map((user) => {
return <User key={user._id} user={user} />;
});
}
});
function collect(connect, monitor) {
console.log("collect");
return {
connectDragSource: connect.dragSource(),
isDragging: monitor.isDragging()
};
}
const userTaskIconSource = {
beginDrag(props) {
return {
id: props.user._id,
user: props.user
};
}
};
var UserTaskIcon = React.createClass({
propTypes: {
connectDragSource: React.PropTypes.func.isRequired,
isDragging: React.PropTypes.bool.isRequired
},
/*
* PRE REACT BUT WORKS FOR INIT BUT NOT AS IDEAL OR FLEXIBLE
*
componentDidMount(){
$( ".draggable" ).draggable({
revert: "invalid"
});
$(".droppable").droppable({
drop: function( event, ui ) {
var userId = event.target.id,
user = Meteor.users.findOne(userId),
taskId = ui.draggable[0].id,
task = Tasks.findOne(taskId);
if(task && user && task.userId !== user._id) {
Meteor.call("changeTaskOwner", user._id, task._id, function(err, res){
if(res) {
toastr.success('You have updated the task.');
}
if(err) {
toastr.error('Error: You have not updated the task.');
}
});
} else {
return false;
}
}
});
},*/
renderTask() {
let taskTitle = this.props.task.clientName + " " + this.props.task.description;
return <a className="btn btn-info btn-xs draggable" id={this.props.task._id} title={taskTitle}><i className="fa fa-arrows"></i> {this.props.task.title}</a>
},
render() {
var isDragging = this.props.isDragging;
var connectDragSource = this.props.connectDragSource;
return connectDragSource(
<div style={{ opacity: isDragging ? 0.5 : 1 }}>{this.renderTask()}</div>
);
}
});
DragSource("userTaskIcon", userTaskIconSource, collect)(UserTaskIcon);
User = React.createClass({
mixins: [ReactMeteorData],
getMeteorData(){
const user = Meteor.users.find({_id: this.props.user._id}).fetch();
const tasks = Tasks.find({ userId: this.props.user._id }).fetch();
const data = {};
if(user){
data.user = user;
}
if (tasks) {
data.tasks = tasks;
}
return data;
},
renderTaskIcons() {
return this.data.tasks.map((task) => {
return <UserTaskIcon key={task._id} task={task} />;
});
},
render () {
const user = this.data.user[0];
return (
<div className="col-sm-3">
{this.data.user ?
<div className="well well-lg">
<h3>{user.username}</h3>
<div className="droppable" id={this.data.user._id}>
{this.renderTaskIcons()}
</div>
</div>
:
null
}
</div>
);
}
});
DragDropContext(ReactDnDBackend)(User);
import { Component, PropTypes } from 'react';
import ReactMixin from 'react-mixin';
import { DragDropContext } from 'react-dnd';
import Tasks from 'app/collections/Tasks';
import HTML5Backend from 'react-dnd-html5-backend';
import UserTaskIcon from './usertaskicon';
@ReactMixin.decorate(ReactMeteorData)
export class UserList extends Component {
getMeteorData() {
return {
users: Meteor.users.find().fetch()
}
}
render () {
return (
<div>
{this.renderUsers()}
</div>
);
}
renderUsers () {
return this.data.users.map((user) => {
return <User key={user._id} user={user} />;
});
}
}
@DragDropContext(HTML5Backend)
@ReactMixin.decorate(ReactMeteorData)
export class User extends Component {
getMeteorData(){
const user = Meteor.users.find({_id: this.props.user._id}).fetch();
const tasks = Tasks.find({ userId: this.props.user._id }).fetch();
const data = {};
if(user){
data.user = user;
}
if (tasks) {
data.tasks = tasks;
}
return data;
}
renderTaskIcons() {
return this.data.tasks.map((task) => {
return <UserTaskIcon key={task._id} task={task} />;
});
}
render () {
const user = this.data.user[0];
return (
<div className="col-sm-3">
{this.data.user ?
<div className="well well-lg">
<h3>{user.username}</h3>
<div className="droppable" id={this.data.user._id}>
{this.renderTaskIcons()}
</div>
</div>
:
null
}
</div>
);
}
}
import { Component, PropTypes } from 'react';
import { DragSource } from 'react-dnd';
const userTaskIconSource = {
beginDrag(props) {
return {
id: props.task._id,
task: props.task
};
}
};
@DragSource("userTaskIcon", userTaskIconSource, (connect, monitor) => ({
connectDragSource: connect.dragSource(),
isDragging: monitor.isDragging()
}))
export default class UserTaskIcon extends Component {
render() {
const isDragging = this.props.isDragging;
const connectDragSource = this.props.connectDragSource;
let taskTitle = this.props.task.clientName + " " + this.props.task.description;
let id = this.props.task._id;
return (
<div>
{
connectDragSource(
<div style={{ opacity: isDragging ? 0.5 : 1 }}><a className="btn btn-info btn-xs draggable" id={id} title={taskTitle}><i className="fa fa-arrows"></i> {taskTitle}</a></div>
)
}
</div>
);
}
};
@grokbot
Copy link
Author

grokbot commented Nov 4, 2015

Warning: Failed propType: Required prop connectDragSource was not specified in UserTaskIcon. Check the render method of User
Warning: Failed propType: Required prop isDragging was not specified in UserTaskIcon. Check the render method of User.

@grokbot
Copy link
Author

grokbot commented Nov 10, 2015

The answer was apparently to migrate to an ES6 module supporting (with decorators) meteor platform.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment