рдореИрдВ Rails5, рдПрдХреНрд╢рди рдХреЗрдмрд▓, рд░рд┐рдПрдХреНрдЯ рдФрд░ рд░реЗрд▓ рдФрд░ рд░рд┐рдПрдХреНрдЯ рдбреАрдПрдирдбреА рдХреЗ рд╕рд╛рде рдПрдХ рдкреАрдУрд╕реА рдмрдирд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рд╣реВрдВред
рдордХрд╕рдж рд╣реИ рдЯреНрд░реЗрд▓реЛ рдЬреИрд╕рд╛ рдРрдк рдмрдирд╛рдирд╛ рд▓реЗрдХрд┐рди рднрд░реНрддреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рд▓рд┐рдПред
рдореЗрд░рд╛ рдореЛрд░реНрдЪрд╛ ReactJS рдореЗрдВ рд╣реИред
рдореЗрд░реЗ рдкрд╛рд╕ 3 рдШрдЯрдХ рд╣реИрдВ, рдкрд╣рд▓рд╛, рдХрдВрдЯреЗрдирд░ рдХреЙрд▓ "рдЙрдореНрдореАрджрд╡рд╛рд░", рдпрд╣ рдШрдЯрдХ 2 "рдХрд╛рд░реНрдбрдмреЛрд░реНрдб" рдШрдЯрдХреЛрдВ рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИ рдЬреЛ "рдХрд╛рд░реНрдб" рдШрдЯрдХ рдХрд╣рддреЗ рд╣реИрдВред
рдореИрдВ рдбреНрд░реИрдЧ рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдХрд╛рд░реНрдб рдФрд░ рдбреНрд░реЙрдк рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдХрд╛рд░реНрдбрдмреЛрд░реНрдб рдХреЗ рд▓рд┐рдП рдбреАрдПрдирдбреА рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдкрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХрд░рддрд╛ рд╣реВрдВред рдЬрдм рдореИрдВ рдХрд╛рд░реНрдбрдмреЛрд░реНрдб рдкрд░ рдХрд╛рд░реНрдб рдЫреЛрдбрд╝рддрд╛ рд╣реВрдВ, рддреЛ рдореИрдВ рдЕрдкрдиреЗ рд░рд╛рдЬреНрдп рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреЛрд╕реНрдЯ рдХреЙрд▓ рдФрд░ рдПрдХ рд╡реЗрдмрд╕реЛрдХреЗрдЯ (рд░реЗрд▓ 5 рд╕реЗ рдПрдХреНрд╢рди рдХреЗрдмрд▓) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВред рдореБрдЭреЗ рд╕рдордЭ рдореЗрдВ рдирд╣реАрдВ рдЖрддрд╛ рдХрд┐ рдкреЛрд╕реНрдЯ рдХреЙрд▓ рдХреЗ рдмрд╛рдж рдореЗрд░реЗ рдкрд╛рд╕ рдпрд╣ рд╕рдВрджреЗрд╢ рдХреНрдпреЛрдВ рд╣реИ:
Uncaught Error: Cannot have two HTML5 backends at the same time.
at HTML5Backend.setup (eval at <anonymous> (webpack-bundle.self-7b1a342тАж.js?body=1:4175), <anonymous>:87:15)
at DragDropManager.handleRefCountChange (eval at <anonymous> (webpack-bundle.self-7b1a342тАж.js?body=1:3566), <anonymous>:52:22)
at Object.dispatch (eval at <anonymous> (webpack-bundle.self-7b1a342тАж.js?body=1:4931), <anonymous>:186:19)
at HandlerRegistry.addSource (eval at <anonymous> (webpack-bundle.self-7b1a342тАж.js?body=1:3594), <anonymous>:104:18)
at registerSource (eval at <anonymous> (webpack-bundle.self-7b1a342тАж.js?body=1:4294), <anonymous>:9:27)
at DragDropContainer.receiveType (eval at <anonymous> (webpack-bundle.self-7b1a342тАж.js?body=1:1793), <anonymous>:146:32)
at DragDropContainer.receiveProps (eval at <anonymous> (webpack-bundle.self-7b1a342тАж.js?body=1:1793), <anonymous>:135:14)
at new DragDropContainer (eval at <anonymous> (webpack-bundle.self-7b1a342тАж.js?body=1:1793), <anonymous>:102:13)
at eval (eval at <anonymous> (webpack-bundle.self-7b1a342тАж.js?body=1:4399), <anonymous>:295:18)
at measureLifeCyclePerf (eval at <anonymous> (webpack-bundle.self-7b1a342тАж.js?body=1:4399), <anonymous>:75:12)
рдЙрдореНрдореАрджрд╡рд╛рд░.рдЬреЗрдПрд╕рдПрдХреНрд╕ =
import React, { PropTypes } from 'react';
import { DragDropContextProvider } from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';
import CardBoard from './CardBoard.jsx';
export default class Candidates extends React.Component {
constructor(props, _railsContext) {
super(props);
this.state = {
candidates: this.props.candidates
}
this.filterByStatus = this.filterByStatus.bind(this)
}
componentDidMount() {
this.setupSubscription();
}
setupSubscription() {
App.candidate = App.cable.subscriptions.create("CandidateChannel", {
connected: () => {
console.log("User connected !")
},
received: (data) => {
this.setState({ candidates: data.candidates })
},
});
}
render() {
return (
<DragDropContextProvider backend={HTML5Backend}>
<div className="recruitment">
{
["├А Rencontrer", "Entretien"].map((status, index) => {
return (
<CardBoard candidates={(this.filterByStatus({status}))} status={status} key={index} />
);
})
}
</div>
</DragDropContextProvider>
);
}
}
рдХрд╛рд░реНрдбрдмреЛрд░реНрдб.рдЬреЗрдПрд╕рдПрдХреНрд╕ =
import React, { PropTypes } from 'react';
import Card from './Card.jsx';
import { DropTarget } from 'react-dnd';
import ItemTypes from './ItemTypes';
const cardTarget = {
drop(props: Props) {
var status = ''
if(props.status == "├А Rencontrer") {
status = 'to_book'
} else {
status = 'interview'
}
return { status: status };
},
};
@DropTarget(ItemTypes.CARD, cardTarget, (connect, monitor) => ({
connectDropTarget: connect.dropTarget(),
isOver: monitor.isOver(),
canDrop: monitor.canDrop(),
}))
export default class CardBoard extends React.Component<Props> {
constructor(props, _railsContext) {
super(props);
}
render() {
const { canDrop, isOver, connectDropTarget } = this.props;
const isActive = canDrop && isOver;
return connectDropTarget(
<div className={`${this.props.status} ui cards`}>
<h2>{`${this.props.status} (${this.props.candidates.length})`}</h2>
{
(this.props.candidates).map((candidate, index) => {
return <Card candidate={candidate} key={index} />
})
}
{ isActive?
'Release to drop' : 'drag a card here'
}
</div>
);
}
}
рдХрд╛рд░реНрдб.рдЬреЗрдПрд╕рдПрдХреНрд╕=
import React, { PropTypes } from 'react';
import { DragSource } from 'react-dnd';
import ItemTypes from './ItemTypes';
const cardSource = {
beginDrag(props) {
return {
candidate_id: props.candidate.id,
};
},
endDrag(props, monitor) {
const item = monitor.getItem();
const dropResult = monitor.getDropResult();
if (dropResult) {
console.log(`You dropped ${item.candidate_id} vers ${dropResult.status} !`);
$.post(`/update_status/${item.candidate_id}/${dropResult.status}`);
}
},
};
@DragSource(ItemTypes.CARD, cardSource, (connect, monitor) => ({
connectDragSource: connect.dragSource(),
isDragging: monitor.isDragging(),
}))
export default class Card extends React.Component {
constructor(props, _railsContext) {
super(props);
}
render() {
const { isDragging, connectDragSource } = this.props;
const { name } = this.props;
const opacity = isDragging ? 0 : 1;
var candidate = this.props.candidate;
return (
connectDragSource(
<div className="card" key={candidate.id} style={{opacity}}>
<div className="content">
<div className="header">{`${candidate.first_name} ${candidate.last_name}`}</div>
<div className="description">
{candidate.job_title}
</div>
<span className="right floated">
<i className="heart outline like icon"></i>
{candidate.average_rate}
</span>
</div>
</div>
)
);
}
}
рдмреЗрд╣рддрд░ рд╕рдордЭ рдХреЗ рд▓рд┐рдП, рдпрд╣рд╛рдБ рдореЗрд░реА рд╕реБрд╡рд┐рдзрд╛ рдФрд░ рдЙрд╕рдХреА рдмрдЧ рдХрд╛ рдПрдХ GIF рд╣реИ:
@antoineBernard рдореИрдВрдиреЗ рд╣рд╛рд▓ рд╣реА рдореЗрдВ рдПрдХ рд╣реА рддреНрд░реБрдЯрд┐ рдХреЛ рджреВрд░ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдореЗрдВ рдкреВрд░рд╛ рджрд┐рди рдмрд┐рддрд╛рдпрд╛ред рдпрд╣ рдЖрдкрдХреА рдЬреИрд╕реА рд╣реА рд╕рдорд╕реНрдпрд╛ рд╣реЛ рд╕рдХрддреА рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИред 2 рдЪреАрдЬреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВ:
<DragDropContextProvider>
рдХреЛ Candidates.jsx
рдХреЗ рдореВрд▓ рдШрдЯрдХ рдореЗрдВ рд▓реЗ рдЬрд╛рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВредDragDropContext
рдХрд╛ рдХреЗрд╡рд▓ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдЖрд░рдВрдн рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдореИрдВрдиреЗ рд╕рдлрд▓рддрд╛ рдХреЗ рд╕рд╛рде @gcorne рдХреЗ рд╕реБрдЭрд╛рд╡ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛редрдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдпрд╣ рдЖрдкрдХреЗ рд▓рд┐рдП рднреА рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛!
рдЗрд╕рдиреЗ рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдо рдХрд┐рдпрд╛: https://github.com/react-dnd/react-dnd/issues/186#issuecomment -282789420
рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдкреБрд░рд╛рдиреЗ рдХреЗ рд░реВрдк рдореЗрдВ рдЪрд┐рд╣реНрдирд┐рдд рдХрд░ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕рдореЗрдВ рд╣рд╛рд▓ рдХреА рдЧрддрд┐рд╡рд┐рдзрд┐ рдирд╣реАрдВ рд╣реИред рдЖрдЧреЗ рдХреЛрдИ рдЧрддрд┐рд╡рд┐рдзрд┐ рдирд╣реАрдВ рд╣реЛрдиреЗ рдкрд░ рдЗрд╕реЗ рдмрдВрдж рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдЖрдкрдХреЗ рдпреЛрдЧрджрд╛рдиреЛрдВ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред
рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА
@antoineBernard рдореИрдВрдиреЗ рд╣рд╛рд▓ рд╣реА рдореЗрдВ рдПрдХ рд╣реА рддреНрд░реБрдЯрд┐ рдХреЛ рджреВрд░ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдореЗрдВ рдкреВрд░рд╛ рджрд┐рди рдмрд┐рддрд╛рдпрд╛ред рдпрд╣ рдЖрдкрдХреА рдЬреИрд╕реА рд╣реА рд╕рдорд╕реНрдпрд╛ рд╣реЛ рд╕рдХрддреА рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИред 2 рдЪреАрдЬреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВ:
<DragDropContextProvider>
рдХреЛCandidates.jsx
рдХреЗ рдореВрд▓ рдШрдЯрдХ рдореЗрдВ рд▓реЗ рдЬрд╛рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВредDragDropContext
рдХрд╛ рдХреЗрд╡рд▓ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдЖрд░рдВрдн рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдореИрдВрдиреЗ рд╕рдлрд▓рддрд╛ рдХреЗ рд╕рд╛рде @gcorne рдХреЗ рд╕реБрдЭрд╛рд╡ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛редрдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдпрд╣ рдЖрдкрдХреЗ рд▓рд┐рдП рднреА рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛!