Skip to content

Commit bca25b7

Browse files
committed
Make GndFormElementEditor Draggable with handles to reorder
1 parent 7f1034b commit bca25b7

File tree

3 files changed

+82
-9
lines changed

3 files changed

+82
-9
lines changed

web/package-lock.json

+10
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

web/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"react-redux-firebase": "^2.1.8",
2222
"react-router": "^4.3.1",
2323
"react-scripts": "2.1.1",
24+
"react-sortable-hoc": "^1.9.1",
2425
"react-swipeable-views": "^0.12.17",
2526
"react-tint": "^2.0.0",
2627
"redux": "^4.0.0",

web/src/components/gnd-feature-type-editor/gnd-form-editor.js

+71-9
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,15 @@ import PropTypes from 'prop-types';
2020
import GndFormElementEditor from './gnd-form-element-editor';
2121
import GndFormWarning from './gnd-form-warning';
2222
import update from 'immutability-helper';
23-
import {Add} from '@material-ui/icons';
23+
import {Add, DragHandle} from '@material-ui/icons';
2424
import Button from '@material-ui/core/Button';
2525
import {withStyles} from '@material-ui/core/styles';
2626
import DeleteForeverIcon from '@material-ui/icons/DeleteForever';
27+
import {
28+
sortableContainer,
29+
sortableElement,
30+
sortableHandle,
31+
} from 'react-sortable-hoc';
2732

2833
const styles = (theme) => ({
2934
button: {
@@ -46,6 +51,19 @@ const styles = (theme) => ({
4651
display: 'block',
4752
width: '100%',
4853
},
54+
sortableElement: {
55+
zIndex: 1300,
56+
'&:hover div[name=sortableHandle]': {
57+
visibility: 'visible',
58+
}
59+
},
60+
sortableHandle: {
61+
textAlign: 'center',
62+
visibility: 'hidden',
63+
'&:hover': {
64+
cursor: 'move',
65+
}
66+
}
4967
});
5068

5169
class GndFormEditor extends React.Component {
@@ -102,21 +120,65 @@ class GndFormEditor extends React.Component {
102120
onChange({id: form.id, defn: undefined});
103121
};
104122

123+
onSortEnd = ({oldIndex, newIndex}) => {
124+
const {form, onChange} = this.props;
125+
const oldIndexElement = form.defn.elements[oldIndex];
126+
const newIndexElement = form.defn.elements[newIndex];
127+
onChange(
128+
update(form, {
129+
defn: {
130+
elements: {
131+
[oldIndex]: {$set: newIndexElement},
132+
[newIndex]: {$set: oldIndexElement}
133+
}
134+
},
135+
})
136+
);
137+
};
138+
105139
render() {
106140
const {form, classes} = this.props;
107141
if (!form || !form.defn || !form.defn.elements) {
108142
return null;
109143
}
110-
const formElements = form.defn.elements.map((element, idx) => (
111-
<GndFormElementEditor
112-
key={element.id}
113-
element={element}
114-
onChange={(el) => this.handleElementChange(el, idx)}
115-
/>
116-
));
144+
145+
const SortableHandle = sortableHandle(() =>
146+
<div className={classes.sortableHandle} name="sortableHandle">
147+
<DragHandle fontSize="inherit"/>
148+
</div>
149+
);
150+
151+
const SortableElement = sortableElement(({element, onChange}) =>
152+
<div className={classes.sortableElement}>
153+
<SortableHandle />
154+
<GndFormElementEditor
155+
key={element.id}
156+
element={element}
157+
onChange={onChange}
158+
/>
159+
</div>
160+
);
161+
162+
const SortableContainer = sortableContainer(({children}) =>
163+
<div>{children}</div>
164+
);
165+
117166
return (
118167
<React.Fragment>
119-
{formElements}
168+
<SortableContainer
169+
onSortEnd={this.onSortEnd}
170+
lockAxis='y'
171+
useDragHandle
172+
>
173+
{form.defn.elements.map((element, index) => (
174+
<SortableElement
175+
key={`item-${index}`}
176+
index={index}
177+
element={element}
178+
onChange={(el) => this.handleElementChange(el, index)}
179+
/>
180+
))}
181+
</SortableContainer>
120182
<div className={classes.bottomControls}>
121183
<span className={classes.bottomLeftControls}>
122184
<Button

0 commit comments

Comments
 (0)