Skip to content

Commit 9b20281

Browse files
committed
Sortable reworked
1 parent dc65aa3 commit 9b20281

File tree

5 files changed

+91
-98
lines changed

5 files changed

+91
-98
lines changed

css/compact_styles.scss

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
}
3636

3737
.group-or-rule-container {
38-
padding-bottom: 5px;
38+
margin-bottom: 5px;
3939
padding-right: 5px;
4040
}
4141

@@ -49,9 +49,3 @@
4949
padding-left: 0;
5050
}
5151

52-
53-
.group-or-rule-container {
54-
padding-bottom: 5px;
55-
padding-right: 5px;
56-
}
57-

css/styles.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@
8383
}
8484

8585
.group-or-rule-container {
86-
padding-bottom: 10px;
86+
margin-bottom: 10px;
8787
padding-right: 10px;
8888
}
8989

examples/demo/demo.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,14 @@ export default class DemoQueryBuilder extends Component {
5050
getChildren(props) {
5151
return (
5252
<div>
53+
<div className="query-builder">
54+
<Builder {...props} />
55+
</div>
56+
<br />
5357
<div>queryBuilderFormat: {stringify(queryBuilderFormat(props.tree, props.config))}</div>
5458
<div>stringFormat: {queryString(props.tree, props.config)}</div>
5559
<div>humanStringFormat: {queryString(props.tree, props.config, true)}</div>
5660
<div>Tree: {stringify(props.tree)}</div>
57-
<div className="query-builder">
58-
<Builder {...props} />
59-
</div>
6061
</div>
6162
)
6263
}

modules/components/containers/SortableContainer.js

Lines changed: 81 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,7 @@ export default (Builder, CanMoveFn = null) => {
3939
var startDragging = this.dragStartInfo;
4040
if (startDragging && startDragging.id) {
4141
dragging.itemInfo = this.tree.items[dragging.id];
42-
43-
if (dragging.itemInfo.index != startDragging.itemInfo.index) {
42+
if (dragging.itemInfo.index != startDragging.itemInfo.index || dragging.itemInfo.parent != startDragging.itemInfo.parent) {
4443
var treeEl = startDragging.treeEl;
4544
var plhEl = this._getPlaceholderNodeEl(treeEl, true);
4645
if (plhEl) {
@@ -53,6 +52,8 @@ export default (Builder, CanMoveFn = null) => {
5352
startDragging.itemInfo = clone(dragging.itemInfo);
5453
startDragging.y = plhEl.offsetTop;
5554
startDragging.clientY += (plY - oldPlY);
55+
56+
this._onDrag(this.mousePos, false);
5657
}
5758
}
5859
}
@@ -126,6 +127,10 @@ export default (Builder, CanMoveFn = null) => {
126127
treeElContainer: treeElContainer,
127128
};
128129
this.didAnySortOnDrag = false;
130+
this.mousePos = {
131+
clientX: e.clientX,
132+
clientY: e.clientY,
133+
};
129134

130135
window.addEventListener('mousemove', this.onDrag);
131136
window.addEventListener('mouseup', this.onDragEnd);
@@ -136,7 +141,7 @@ export default (Builder, CanMoveFn = null) => {
136141
}
137142

138143

139-
_onDrag (e) {
144+
_onDrag (e, doHandleDrag = true) {
140145
var dragging = this.draggingInfo;
141146
var startDragging = this.dragStartInfo;
142147
var paddingLeft = this.props.paddingLeft;
@@ -147,6 +152,11 @@ export default (Builder, CanMoveFn = null) => {
147152
return;
148153
}
149154

155+
this.mousePos = {
156+
clientX: e.clientX,
157+
clientY: e.clientY,
158+
};
159+
150160
//first init plX/plY
151161
if (!startDragging.plX) {
152162
var treeEl = startDragging.treeEl;
@@ -170,12 +180,13 @@ export default (Builder, CanMoveFn = null) => {
170180
dragging.y = pos.y;
171181
dragging.paddingLeft = paddingLeft;
172182

173-
var moved = this.handleDrag(dragging, e, CanMoveFn);
183+
var moved = doHandleDrag ? this.handleDrag(dragging, e, CanMoveFn) : false;
174184

175185
if (moved) {
176186
this.didAnySortOnDrag = true;
177187
} else {
178-
e.preventDefault();
188+
if (e.preventDefault)
189+
e.preventDefault();
179190
}
180191

181192
this.setState({
@@ -198,6 +209,7 @@ export default (Builder, CanMoveFn = null) => {
198209
this.setState({
199210
dragging: this.draggingInfo
200211
});
212+
this.mousePos = {};
201213

202214
treeEl.classList.remove("qb-dragging");
203215
this._cacheEls = {};
@@ -251,13 +263,9 @@ export default (Builder, CanMoveFn = null) => {
251263
} else {
252264
var isGroup = hovCNodeEl.classList.contains('group-container');
253265
var hovNodeId = hovCNodeEl.getAttribute('data-id');
254-
var hovEl = null;
255-
if (isGroup) {
256-
var hovInnerEls = hovCNodeEl.getElementsByClassName('group--header');
257-
var hovEl = hovInnerEls.length ? hovInnerEls[0] : null;
258-
} else {
259-
hovEl = hovCNodeEl;
260-
}
266+
var hovEl = hovCNodeEl;
267+
var onlyAppend = false;
268+
var onlyPrepend = false;
261269
if (hovEl) {
262270
var hovRect = hovEl.getBoundingClientRect();
263271
var hovHeight = hovRect.bottom - hovRect.top;
@@ -272,94 +280,82 @@ export default (Builder, CanMoveFn = null) => {
272280
if (trgEl)
273281
trgRect = trgEl.getBoundingClientRect();
274282
} else {
275-
var isOverHover = (dragDirs.vrt < 0 //up
276-
? ((hovRect.bottom - dragRect.top) > hovHeight/2)
277-
: ((dragRect.bottom - hovRect.top) > hovHeight/2));
278-
if (isOverHover) {
279-
trgII = hovII;
280-
trgRect = hovRect;
281-
trgEl = hovEl;
282-
} else {
283-
var trgII = dragDirs.vrt <= 0 //up
284-
? Object.values(this.tree.items).find(it => it.top == (hovII.top + 1)) //below
285-
: Object.values(this.tree.items).find(it => it.top == (hovII.top - 1)); //above
286-
if (trgII) {
287-
if (trgII.id == dragId) {
288-
trgEl = plhEl;
289-
} else
290-
trgEl = this._getNodeElById(treeEl, trgII.id);
291-
trgRect = trgEl.getBoundingClientRect();
283+
if (isGroup) {
284+
if (dragDirs.vrt > 0) { //down
285+
//take group header (for prepend only)
286+
var hovInnerEl = hovCNodeEl.getElementsByClassName('group--header');
287+
var hovEl2 = hovInnerEl.length ? hovInnerEl[0] : null;
288+
var hovRect2 = hovEl2.getBoundingClientRect();
289+
var hovHeight2 = hovRect2.bottom - hovRect2.top;
290+
var isOverHover = ((dragRect.bottom - hovRect2.top) > hovHeight2*3/4);
291+
if (isOverHover && hovII.top > dragInfo.itemInfo.top) {
292+
trgII = hovII;
293+
trgRect = hovRect2;
294+
trgEl = hovEl2;
295+
onlyPrepend = true;
296+
}
297+
} else if (dragDirs.vrt < 0) { //up
298+
if (hovII.lev >= itemInfo.lev) {
299+
//take whole group
300+
var isClimbToHover = ((hovRect.bottom - dragRect.top) >= 5); //todo: 5 is magic for now, configure it!
301+
if (isClimbToHover && hovII.top < dragInfo.itemInfo.top) {
302+
trgII = hovII;
303+
trgRect = hovRect;
304+
trgEl = hovEl;
305+
onlyAppend = true;
306+
}
307+
}
308+
}
309+
if (!onlyPrepend && !onlyAppend) {
310+
//take whole group and check if we can move before/after group
311+
var isOverHover = (dragDirs.vrt < 0 //up
312+
? ((hovRect.bottom - dragRect.top) > (hovHeight-2))
313+
: ((dragRect.bottom - hovRect.top) > (hovHeight-2)));
314+
if (isOverHover) {
315+
trgII = hovII;
316+
trgRect = hovRect;
317+
trgEl = hovEl;
318+
}
292319
}
320+
} else {
321+
//check if we can move before/after group
322+
var isOverHover = (dragDirs.vrt < 0 //up
323+
? ((hovRect.bottom - dragRect.top) > hovHeight/2)
324+
: ((dragRect.bottom - hovRect.top) > hovHeight/2));
325+
if (isOverHover) {
326+
trgII = hovII;
327+
trgRect = hovRect;
328+
trgEl = hovEl;
329+
}
293330
}
294331
}
295332

296333
var isSamePos = (trgII && trgII.id == dragId);
297334
if (trgRect) {
298335
var dragLeftOffset = dragRect.left - treeRect.left;
299336
var trgLeftOffset = trgRect.left - treeRect.left;
300-
//if (isSamePos) {
301-
// dragLeftOffset += 1; //?
302-
//}
303337
var trgLev = trgLeftOffset / paddingLeft;
304338
var dragLev = Math.max(0, Math.round(dragLeftOffset / paddingLeft));
305339
var availMoves = [];
306340
if (isSamePos) {
307-
//allow to move only left/right
308-
var tmp = trgII;
309-
while (tmp.parent && !tmp.next) {
310-
var parII = this.tree.items[tmp.parent];
311-
if (parII.id != 1)
312-
availMoves.push([constants.PLACEMENT_AFTER, parII, parII.lev]);
313-
tmp = parII;
314-
}
315-
if (trgII.prev) {
316-
var tmp = this.tree.items[trgII.prev];
317-
while (!tmp.leaf) {
318-
if (itemInfo.parent != tmp.id)
319-
availMoves.push([constants.PLACEMENT_APPEND, tmp, tmp.lev+1]);
320-
if (!tmp.children || !tmp.children.length || tmp.collapsed) {
321-
break;
322-
} else {
323-
var lastChildId = tmp.children[tmp.children.length - 1];
324-
var lastChildII = this.tree.items[lastChildId];
325-
tmp = lastChildII;
326-
}
327-
}
328-
}
341+
//do nothing
329342
} else {
330343
//find out where we can move..
331-
if (dragDirs.vrt < 0) {
332-
availMoves.push([constants.PLACEMENT_BEFORE, trgII, trgII.lev]);
333-
}
334-
if (dragDirs.vrt > 0 && (trgII.leaf || trgII.collapsed)) {
335-
availMoves.push([constants.PLACEMENT_AFTER, trgII, trgII.lev]);
336-
}
337-
if (!trgII.leaf && dragDirs.vrt > 0) {
338-
availMoves.push([constants.PLACEMENT_PREPEND, trgII, trgII.lev+1]);
339-
}
340-
if (dragDirs.vrt > 0) {
341-
var tmp = trgII;
342-
while (tmp.parent && !tmp.next) {
343-
var parII = this.tree.items[tmp.parent];
344-
availMoves.push([constants.PLACEMENT_APPEND, parII, parII.lev+1]);
345-
tmp = parII;
346-
}
344+
if (isGroup) {
345+
if (onlyAppend) {
346+
availMoves.push([constants.PLACEMENT_APPEND, trgII, trgII.lev+1]);
347+
}
348+
if (onlyPrepend) {
349+
availMoves.push([constants.PLACEMENT_PREPEND, trgII, trgII.lev+1]);
350+
}
347351
}
348-
if (dragDirs.vrt < 0) {
349-
if (trgII.prev) {
350-
var tmp = this.tree.items[trgII.prev];
351-
while (!tmp.leaf) {
352-
if (itemInfo.parent != tmp.id)
353-
availMoves.push([constants.PLACEMENT_APPEND, tmp, tmp.lev+1]);
354-
if (!tmp.children || !tmp.children.length || tmp.collapsed) {
355-
break;
356-
} else {
357-
var lastChildId = tmp.children[tmp.children.length - 1];
358-
var lastChildII = this.tree.items[lastChildId];
359-
tmp = lastChildII;
360-
}
352+
if (!onlyAppend && !onlyPrepend) {
353+
if (dragDirs.vrt < 0) {
354+
availMoves.push([constants.PLACEMENT_BEFORE, trgII, trgII.lev]);
355+
}
356+
if (dragDirs.vrt > 0 && (trgII.leaf || trgII.collapsed || !trgII.leaf && trgII.top < dragInfo.itemInfo.top)) {
357+
availMoves.push([constants.PLACEMENT_AFTER, trgII, trgII.lev]);
361358
}
362-
}
363359
}
364360
}
365361

@@ -413,14 +409,14 @@ export default (Builder, CanMoveFn = null) => {
413409
bestMode = availMoves.find(am => am[2] == closestDragLev);
414410
if (!isSamePos && !bestMode && availMoves.length)
415411
bestMode = availMoves[0];
416-
417412
moveInfo = bestMode;
418413
}
419414
}
420415
}
421416
}
422417

423418
if (moveInfo) {
419+
console.log('moveInfo', moveInfo);
424420
this.move(itemInfo, moveInfo[1], moveInfo[0], moveInfo[3]);
425421
return true;
426422
}

modules/utils/treeUtils.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import Immutable from 'immutable';
2+
import clone from 'clone';
23

34
export const getFlatTree = (tree) => {
45

@@ -25,7 +26,7 @@ export const getFlatTree = (tree) => {
2526
_flatizeTree(child, path.concat(id), insideCollapsed || collapsed, lev + 1, subinfo);
2627
});
2728
if (!collapsed) {
28-
info.height = (info.height || 0) + subinfo.height;
29+
info.height = (info.height || 0) + (subinfo.height || 0);
2930
}
3031
}
3132
let itemsAfter = flat.length;
@@ -38,13 +39,14 @@ export const getFlatTree = (tree) => {
3839
path: path.concat(id),
3940
lev: lev,
4041
leaf: !children,
41-
index: flat.length,
42+
index: itemsBefore,
4243
id: id,
4344
children: childrenIds,
4445
_top: itemsBefore,
4546
_height: (itemsAfter - itemsBefore),
4647
top: (insideCollapsed ? null : top),
4748
height: height,
49+
bottom: (insideCollapsed ? null : top) + height,
4850
collapsed: collapsed,
4951
node: item,
5052
};

0 commit comments

Comments
 (0)