mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	add sort strategies via react-dnd
This commit is contained in:
		
							parent
							
								
									4d5c901807
								
							
						
					
					
						commit
						7243dce22d
					
				| @ -40,6 +40,8 @@ | ||||
|     "normalize.css": "^5.0.0", | ||||
|     "react": "^15.3.1", | ||||
|     "react-addons-css-transition-group": "^15.3.1", | ||||
|     "react-dnd": "^2.1.4", | ||||
|     "react-dnd-html5-backend": "^2.1.2", | ||||
|     "react-dom": "^15.3.1", | ||||
|     "react-mdl": "^1.9.0", | ||||
|     "react-modal": "^1.6.4", | ||||
|  | ||||
| @ -39,6 +39,10 @@ const prepare = (methods, dispatch) => { | ||||
|         methods.updateInList('strategies', index, n); | ||||
|     }; | ||||
| 
 | ||||
|     methods.moveStrategy = (index, toIndex) => { | ||||
|         methods.moveItem('strategies', index, toIndex); | ||||
|     }; | ||||
| 
 | ||||
|     methods.removeStrategy = (index) => { | ||||
|         methods.removeFromList('strategies', index); | ||||
|     }; | ||||
|  | ||||
| @ -45,6 +45,10 @@ const prepare =  (methods, dispatch) => { | ||||
|         methods.removeFromList('strategies', index); | ||||
|     }; | ||||
| 
 | ||||
|     methods.moveStrategy = (index, toIndex) => { | ||||
|         methods.moveItem('strategies', index, toIndex); | ||||
|     }; | ||||
| 
 | ||||
|     methods.updateStrategy = (index, n) => { | ||||
|         methods.updateInList('strategies', index, n); | ||||
|     }; | ||||
|  | ||||
| @ -29,6 +29,7 @@ class AddFeatureToggleComponent extends Component { | ||||
|             addStrategy, | ||||
|             removeStrategy, | ||||
|             updateStrategy, | ||||
|             moveStrategy, | ||||
|             onSubmit, | ||||
|             onCancel, | ||||
|             editmode = false, | ||||
| @ -81,6 +82,7 @@ class AddFeatureToggleComponent extends Component { | ||||
|                     configuredStrategies={configuredStrategies} | ||||
|                     addStrategy={addStrategy} | ||||
|                     updateStrategy={updateStrategy} | ||||
|                     moveStrategy={moveStrategy} | ||||
|                     removeStrategy={removeStrategy} /> | ||||
| 
 | ||||
|                 <br /> | ||||
|  | ||||
| @ -1,6 +1,9 @@ | ||||
| import React, { PropTypes } from 'react'; | ||||
| import ConfigureStrategy from './strategy-configure'; | ||||
| import { DragDropContext } from 'react-dnd'; | ||||
| import HTML5Backend from 'react-dnd-html5-backend'; | ||||
| 
 | ||||
| @DragDropContext(HTML5Backend) // eslint-disable-line new-cap | ||||
| class StrategiesList extends React.Component { | ||||
| 
 | ||||
|     static propTypes () { | ||||
| @ -9,6 +12,7 @@ class StrategiesList extends React.Component { | ||||
|             configuredStrategies: PropTypes.array.isRequired, | ||||
|             updateStrategy: PropTypes.func.isRequired, | ||||
|             removeStrategy: PropTypes.func.isRequired, | ||||
|             moveStrategy: PropTypes.func.isRequired, | ||||
|         }; | ||||
|     } | ||||
| 
 | ||||
| @ -16,6 +20,9 @@ class StrategiesList extends React.Component { | ||||
|         const { | ||||
|             strategies, | ||||
|             configuredStrategies, | ||||
|             moveStrategy, | ||||
|             removeStrategy, | ||||
|             updateStrategy, | ||||
|         } = this.props; | ||||
| 
 | ||||
|         if (!configuredStrategies || configuredStrategies.length === 0) { | ||||
| @ -24,10 +31,12 @@ class StrategiesList extends React.Component { | ||||
| 
 | ||||
|         const blocks = configuredStrategies.map((strategy, i) => ( | ||||
|             <ConfigureStrategy | ||||
|                 index={i} | ||||
|                 key={`${strategy.name}-${i}`} | ||||
|                 strategy={strategy} | ||||
|                 removeStrategy={this.props.removeStrategy.bind(null, i)} | ||||
|                 updateStrategy={this.props.updateStrategy.bind(null, i)} | ||||
|                 moveStrategy={moveStrategy} | ||||
|                 removeStrategy={removeStrategy.bind(null, i)} | ||||
|                 updateStrategy={updateStrategy.bind(null, i)} | ||||
|                 strategyDefinition={strategies.find(s => s.name === strategy.name)} /> | ||||
|         )); | ||||
|         return ( | ||||
|  | ||||
| @ -3,7 +3,8 @@ import { | ||||
|     Textfield, Button, | ||||
|     Card, CardTitle, CardText, CardActions, CardMenu, | ||||
|     IconButton, Icon, | ||||
| }  from 'react-mdl'; | ||||
| } from 'react-mdl'; | ||||
| import { DragSource, DropTarget } from 'react-dnd'; | ||||
| import { Link } from 'react-router'; | ||||
| import StrategyInputPercentage from './strategy-input-percentage'; | ||||
| import StrategyInputList from './strategy-input-list'; | ||||
| @ -13,7 +14,6 @@ const style = { | ||||
|     minWidth: '300px', | ||||
|     maxWidth: '100%', | ||||
|     margin: '5px 20px 15px 0px', | ||||
|     background: '#f2f9fc', | ||||
| }; | ||||
| 
 | ||||
| const helpText = { | ||||
| @ -21,6 +21,34 @@ const helpText = { | ||||
|     fontSize: '12px', | ||||
|     lineHeight: '14px', | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| const dragSource = { | ||||
|     beginDrag (props) { | ||||
|         return { | ||||
|             index: props.index, | ||||
|         }; | ||||
|     }, | ||||
| }; | ||||
| 
 | ||||
| const dragTarget = { | ||||
|     drop (props, monitor) { | ||||
|         const dragIndex = monitor.getItem().index; | ||||
|         const toIndex = props.index; | ||||
|         if (dragIndex !== toIndex) { | ||||
|             props.moveStrategy(dragIndex, toIndex); | ||||
|         } | ||||
|     }, | ||||
| }; | ||||
| 
 | ||||
| @DropTarget('strategy', dragTarget, connect => ({ // eslint-disable-line new-cap | ||||
|     connectDropTarget: connect.dropTarget(), | ||||
| })) | ||||
| @DragSource('strategy', dragSource, (connect, monitor) => ({ // eslint-disable-line new-cap | ||||
|     connectDragSource: connect.dragSource(), | ||||
|     connectDragPreview: connect.dragPreview(), | ||||
|     isDragging: monitor.isDragging(), | ||||
| })) | ||||
| class StrategyConfigure extends React.Component { | ||||
| 
 | ||||
|     static propTypes () { | ||||
| @ -29,13 +57,14 @@ class StrategyConfigure extends React.Component { | ||||
|             strategyDefinition: PropTypes.object.isRequired, | ||||
|             updateStrategy: PropTypes.func.isRequired, | ||||
|             removeStrategy: PropTypes.func.isRequired, | ||||
|             moveStrategy: PropTypes.func.isRequired, | ||||
|             isDragging: PropTypes.bool.isRequired, | ||||
|             connectDragPreview: PropTypes.func.isRequired, | ||||
|             connectDragSource: PropTypes.func.isRequired, | ||||
|             connectDropTarget: PropTypes.func.isRequired, | ||||
|         }; | ||||
|     } | ||||
| 
 | ||||
|     // shouldComponentUpdate (props, nextProps) { | ||||
|     //     console.log({ props, nextProps }); | ||||
|     // } | ||||
| 
 | ||||
|     handleConfigChange = (key, e) => { | ||||
|         this.setConfig(key, e.target.value); | ||||
|     }; | ||||
| @ -98,7 +127,7 @@ class StrategyConfigure extends React.Component { | ||||
|                                 label={name} | ||||
|                                 onChange={this.handleConfigChange.bind(this, name)} | ||||
|                                 value={value} | ||||
|                             /> | ||||
|                                 /> | ||||
|                             {description && <p style={helpText}>{description}</p>} | ||||
|                         </div> | ||||
|                     ); | ||||
| @ -114,7 +143,7 @@ class StrategyConfigure extends React.Component { | ||||
|                                 label={name} | ||||
|                                 onChange={this.handleConfigChange.bind(this, name)} | ||||
|                                 value={value} | ||||
|                             /> | ||||
|                                 /> | ||||
|                             {description && <p style={helpText}>{description}</p>} | ||||
|                         </div> | ||||
|                     ); | ||||
| @ -125,9 +154,46 @@ class StrategyConfigure extends React.Component { | ||||
|     } | ||||
| 
 | ||||
|     render () { | ||||
|         if (!this.props.strategyDefinition) { | ||||
|         const { isDragging, connectDragPreview, connectDragSource, connectDropTarget } = this.props; | ||||
| 
 | ||||
|         let item; | ||||
|         if (this.props.strategyDefinition) { | ||||
|             const inputFields = this.renderInputFields(this.props.strategyDefinition); | ||||
|             const { name } = this.props.strategy; | ||||
|             return ( | ||||
|             item = ( | ||||
|                 <Card shadow={0} style={{ background: '#f2f9fc', width: '100%', display: 'block', opacity: isDragging ? '0.1' : '1' }}> | ||||
|                     <CardTitle style={{ color: '#fff', height: '65px', background: '#607d8b' }}> | ||||
|                         <Icon name="extension" /> {name} | ||||
|                     </CardTitle> | ||||
|                     <CardText> | ||||
|                         {this.props.strategyDefinition.description} | ||||
|                     </CardText> | ||||
|                     { | ||||
|                         inputFields && <CardActions border style={{ padding: '20px' }}> | ||||
|                             {inputFields} | ||||
|                         </CardActions> | ||||
|                     } | ||||
| 
 | ||||
|                     <CardMenu style={{ color: '#fff' }}> | ||||
|                         <Link | ||||
|                             title="View strategy" | ||||
|                             to={`/strategies/view/${name}`} | ||||
|                             style={{ color: '#fff', display: 'inline-block', verticalAlign: 'bottom', marginRight: '5px' }}> | ||||
|                             <Icon name="link" /> | ||||
|                         </Link> | ||||
|                         <IconButton title="Remove strategy from toggle" name="delete" onClick={this.handleRemove} /> | ||||
|                         {connectDragSource( | ||||
|                             <span style={{ | ||||
|                                 cursor: 'pointer', | ||||
|                                 display: 'inline-block', | ||||
|                                 verticalAlign: 'bottom', | ||||
|                             }}><Icon name="reorder" /></span>)} | ||||
|                     </CardMenu> | ||||
|                 </Card> | ||||
|             ); | ||||
|         } else { | ||||
|             const { name } = this.props.strategy; | ||||
|             item = ( | ||||
|                 <Card shadow={0} style={style}> | ||||
|                     <CardTitle>"{name}" deleted?</CardTitle> | ||||
|                     <CardText> | ||||
| @ -142,35 +208,9 @@ class StrategyConfigure extends React.Component { | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
|         const inputFields = this.renderInputFields(this.props.strategyDefinition); | ||||
| 
 | ||||
|         const { name } = this.props.strategy; | ||||
| 
 | ||||
|         return ( | ||||
|             <Card shadow={0} style={style}> | ||||
|                 <CardTitle style={{ color: '#fff', height: '65px', background: '#607d8b' }}> | ||||
|                     <Icon name="extension" /> { name } | ||||
|                 </CardTitle> | ||||
|                 <CardText> | ||||
|                     {this.props.strategyDefinition.description} | ||||
|                 </CardText> | ||||
|                 { | ||||
|                     inputFields && <CardActions border style={{ padding: '20px' }}> | ||||
|                         {inputFields} | ||||
|                     </CardActions> | ||||
|                 } | ||||
| 
 | ||||
|                 <CardMenu style={{ color: '#fff' }}> | ||||
|                     <Link | ||||
|                         title="View strategy" | ||||
|                         to={`/strategies/view/${name}`} | ||||
|                         style={{ color: '#fff', display: 'inline-block', verticalAlign: 'bottom', marginRight: '5px' }}> | ||||
|                         <Icon name="link" /> | ||||
|                     </Link> | ||||
|                     <IconButton title="Remove strategy from toggle" name="delete" onClick={this.handleRemove} /> | ||||
|                 </CardMenu> | ||||
|             </Card> | ||||
|         ); | ||||
|         return (connectDropTarget(connectDragPreview( | ||||
|             <div style={style}>{item}</div> | ||||
|         ))); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -6,6 +6,7 @@ import { | ||||
|     createPush, | ||||
|     createUp, | ||||
|     createInit, | ||||
|     createMove, | ||||
| } from '../store/input-actions'; | ||||
| 
 | ||||
| function getId (id, ownProps) { | ||||
| @ -57,6 +58,10 @@ export function createActions ({ id, prepare = (v) => v }) { | ||||
|             dispatch(createPop({ id: getId(id, ownProps), key, index })); | ||||
|         }, | ||||
| 
 | ||||
|         moveItem (key, index, toIndex) { | ||||
|             dispatch(createMove({ id: getId(id, ownProps), key, index, toIndex })); | ||||
|         }, | ||||
| 
 | ||||
|         updateInList (key, index, newValue, merge = false) { | ||||
|             dispatch(createUp({ id: getId(id, ownProps), key, index, newValue, merge })); | ||||
|         }, | ||||
|  | ||||
| @ -6,6 +6,7 @@ export const actions = { | ||||
|     LIST_UP: 'LIST_UP', | ||||
|     CLEAR: 'CLEAR', | ||||
|     INIT: 'INIT', | ||||
|     MOVE: 'MOVE', | ||||
| }; | ||||
| 
 | ||||
| export const createInit = ({ id, value }) => ({ type: actions.INIT, id, value }); | ||||
| @ -13,6 +14,7 @@ export const createInc = ({ id, key }) => ({ type: actions.INCREMENT_VALUE, id, | ||||
| export const createSet = ({ id, key, value }) => ({ type: actions.SET_VALUE, id, key, value }); | ||||
| export const createPush = ({ id, key, value }) => ({ type: actions.LIST_PUSH, id, key, value }); | ||||
| export const createPop = ({ id, key, index }) => ({ type: actions.LIST_POP, id, key, index }); | ||||
| export const createMove = ({ id, key, index, toIndex }) => ({ type: actions.MOVE, id, key, index, toIndex }); | ||||
| export const createUp = ({ id, key, index, newValue, merge }) => ({ type: actions.LIST_UP, id, key, index, newValue, merge }); | ||||
| export const createClear = ({ id }) => ({ type: actions.CLEAR, id }); | ||||
| 
 | ||||
|  | ||||
| @ -69,6 +69,13 @@ function removeFromList (state, { id, key, index }) { | ||||
|     return state.updateIn(id.concat([key]), (list) => list.remove(index)); | ||||
| } | ||||
| 
 | ||||
| function move (state, { id, key, index, toIndex }) { | ||||
|     return state.updateIn(id.concat([key]), list => { | ||||
|         const olditem = list.get(index); | ||||
|         return list.delete(index).insert(toIndex, olditem); | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
| const inputState = (state = getInitState(), action) => { | ||||
|     if (!action.id) { | ||||
|         return state; | ||||
| @ -88,6 +95,8 @@ const inputState = (state = getInitState(), action) => { | ||||
|             return addToList(state, action); | ||||
|         case actions.LIST_POP: | ||||
|             return removeFromList(state, action); | ||||
|         case actions.MOVE: | ||||
|             return move(state, action); | ||||
|         case actions.LIST_UP: | ||||
|             return updateInList(state, action); | ||||
|         case actions.CLEAR: | ||||
|  | ||||
| @ -1,5 +1,6 @@ | ||||
| { | ||||
|   "globalDependencies": { | ||||
|     "react-dnd": "registry:dt/react-dnd#2.0.2+20161111212335", | ||||
|     "react-mdl": "registry:dt/react-mdl#0.0.0+20160830142027" | ||||
|   } | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user