Much better sidebar sorting (#308)

This commit is contained in:
Gregory Schier 2017-06-13 13:45:15 -07:00 committed by GitHub
parent 4e61c699ab
commit 8cf491a99d
8 changed files with 63 additions and 139 deletions

View File

@ -1,7 +1,7 @@
{
"private": true,
"name": "insomnia",
"version": "5.3.0",
"version": "5.3.1",
"productName": "Insomnia",
"longName": "Insomnia REST Client",
"description": "Debug APIs like a human, not a robot",

View File

@ -11,8 +11,7 @@ class SidebarChildren extends PureComponent {
handleDuplicateRequest,
handleDuplicateRequestGroup,
handleGenerateCode,
moveRequest,
moveRequestGroup,
moveDoc,
handleActivateRequest,
activeRequest,
workspace
@ -29,7 +28,7 @@ class SidebarChildren extends PureComponent {
return (
<SidebarRequestRow
key={child.doc._id}
moveRequest={moveRequest}
moveDoc={moveDoc}
handleActivateRequest={handleActivateRequest}
handleDuplicateRequest={handleDuplicateRequest}
handleGenerateCode={handleGenerateCode}
@ -66,8 +65,7 @@ class SidebarChildren extends PureComponent {
handleActivateRequest={handleActivateRequest}
key={requestGroup._id}
isActive={isActive}
moveRequestGroup={moveRequestGroup}
moveRequest={moveRequest}
moveDoc={moveDoc}
handleSetRequestGroupCollapsed={handleSetRequestGroupCollapsed}
handleDuplicateRequestGroup={handleDuplicateRequestGroup}
isCollapsed={child.collapsed}
@ -102,8 +100,7 @@ SidebarChildren.propTypes = {
handleDuplicateRequest: PropTypes.func.isRequired,
handleDuplicateRequestGroup: PropTypes.func.isRequired,
handleGenerateCode: PropTypes.func.isRequired,
moveRequest: PropTypes.func.isRequired,
moveRequestGroup: PropTypes.func.isRequired,
moveDoc: PropTypes.func.isRequired,
childObjects: PropTypes.arrayOf(PropTypes.object).isRequired,
workspace: PropTypes.object.isRequired,

View File

@ -42,7 +42,7 @@ class SidebarRequestGroupRow extends PureComponent {
const {
connectDragSource,
connectDropTarget,
moveRequest,
moveDoc,
children,
requestGroup,
isCollapsed,
@ -104,7 +104,7 @@ class SidebarRequestGroupRow extends PureComponent {
handleActivateRequest={misc.nullFn}
handleDuplicateRequest={misc.nullFn}
handleGenerateCode={misc.nullFn}
moveRequest={moveRequest}
moveDoc={moveDoc}
isActive={false}
request={null}
requestGroup={requestGroup}
@ -122,8 +122,7 @@ SidebarRequestGroupRow.propTypes = {
// Functions
handleSetRequestGroupCollapsed: PropTypes.func.isRequired,
handleDuplicateRequestGroup: PropTypes.func.isRequired,
moveRequestGroup: PropTypes.func.isRequired,
moveRequest: PropTypes.func.isRequired,
moveDoc: PropTypes.func.isRequired,
handleActivateRequest: PropTypes.func.isRequired,
handleCreateRequest: PropTypes.func.isRequired,
handleCreateRequestGroup: PropTypes.func.isRequired,
@ -167,10 +166,14 @@ function isAbove (monitor, component) {
const dragTarget = {
drop (props, monitor, component) {
const movingDoc = monitor.getItem().requestGroup || monitor.getItem().request;
const parentId = props.requestGroup.parentId;
const targetId = props.requestGroup._id;
if (isAbove(monitor, component)) {
props.moveRequestGroup(monitor.getItem().requestGroup, props.requestGroup, 1);
props.moveDoc(movingDoc, parentId, targetId, 1);
} else {
props.moveRequestGroup(monitor.getItem().requestGroup, props.requestGroup, -1);
props.moveDoc(movingDoc, parentId, targetId, -1);
}
},
hover (props, monitor, component) {
@ -196,5 +199,5 @@ function targetCollect (connect, monitor) {
};
}
const source = DragSource('SIDEBAR_REQUEST_GROUP_ROW', dragSource, sourceCollect)(SidebarRequestGroupRow);
export default DropTarget('SIDEBAR_REQUEST_GROUP_ROW', dragTarget, targetCollect)(source);
const source = DragSource('SIDEBAR_REQUEST_ROW', dragSource, sourceCollect)(SidebarRequestGroupRow);
export default DropTarget('SIDEBAR_REQUEST_ROW', dragTarget, targetCollect)(source);

View File

@ -163,7 +163,7 @@ SidebarRequestRow.propTypes = {
handleDuplicateRequest: PropTypes.func.isRequired,
handleGenerateCode: PropTypes.func.isRequired,
requestCreate: PropTypes.func.isRequired,
moveRequest: PropTypes.func.isRequired,
moveDoc: PropTypes.func.isRequired,
// Other
isActive: PropTypes.bool.isRequired,
@ -197,18 +197,15 @@ function isAbove (monitor, component) {
const dragTarget = {
drop (props, monitor, component) {
const {request} = monitor.getItem();
const targetRequest = props.request;
const movingDoc = monitor.getItem().requestGroup || monitor.getItem().request;
const {requestGroup} = props;
const requestGroupId = requestGroup ? requestGroup._id : null;
const parentId = targetRequest ? targetRequest.parentId : requestGroupId;
const targetId = targetRequest ? targetRequest._id : null;
const parentId = props.requestGroup ? props.requestGroup._id : props.request.parentId;
const targetId = props.request ? props.request._id : null;
if (isAbove(monitor, component)) {
props.moveRequest(request, parentId, targetId, 1);
props.moveDoc(movingDoc, parentId, targetId, 1);
} else {
props.moveRequest(request, parentId, targetId, -1);
props.moveDoc(movingDoc, parentId, targetId, -1);
}
},
hover (props, monitor, component) {

View File

@ -47,8 +47,7 @@ class Sidebar extends PureComponent {
handleGenerateCode,
handleCreateRequestGroup,
handleSetRequestGroupCollapsed,
moveRequest,
moveRequestGroup,
moveDoc,
handleActivateRequest,
activeRequest
} = this.props;
@ -99,8 +98,7 @@ class Sidebar extends PureComponent {
handleDuplicateRequest={handleDuplicateRequest}
handleDuplicateRequestGroup={handleDuplicateRequestGroup}
handleGenerateCode={handleGenerateCode}
moveRequest={moveRequest}
moveRequestGroup={moveRequestGroup}
moveDoc={moveDoc}
workspace={workspace}
activeRequest={activeRequest}
/>
@ -124,8 +122,7 @@ Sidebar.propTypes = {
handleExportFile: PropTypes.func.isRequired,
handleSetActiveWorkspace: PropTypes.func.isRequired,
handleSetActiveEnvironment: PropTypes.func.isRequired,
moveRequest: PropTypes.func.isRequired,
moveRequestGroup: PropTypes.func.isRequired,
moveDoc: PropTypes.func.isRequired,
handleCreateRequest: PropTypes.func.isRequired,
handleCreateRequestGroup: PropTypes.func.isRequired,
handleDuplicateRequest: PropTypes.func.isRequired,

View File

@ -252,8 +252,7 @@ class Wrapper extends PureComponent {
handleDuplicateRequest,
handleDuplicateRequestGroup,
handleExportFile,
handleMoveRequest,
handleMoveRequestGroup,
handleMoveDoc,
handleResetDragPaneHorizontal,
handleResetDragPaneVertical,
handleResetDragSidebar,
@ -312,8 +311,7 @@ class Wrapper extends PureComponent {
handleGenerateCode={handleGenerateCode}
handleDuplicateRequestGroup={handleDuplicateRequestGroup}
handleSetActiveEnvironment={handleSetActiveEnvironment}
moveRequest={handleMoveRequest}
moveRequestGroup={handleMoveRequestGroup}
moveDoc={handleMoveDoc}
handleSetRequestGroupCollapsed={handleSetRequestGroupCollapsed}
activeRequest={activeRequest}
activeEnvironment={activeEnvironment}
@ -523,8 +521,7 @@ Wrapper.propTypes = {
handleExportFile: PropTypes.func.isRequired,
handleSetActiveWorkspace: PropTypes.func.isRequired,
handleSetActiveEnvironment: PropTypes.func.isRequired,
handleMoveRequest: PropTypes.func.isRequired,
handleMoveRequestGroup: PropTypes.func.isRequired,
handleMoveDoc: PropTypes.func.isRequired,
handleCreateRequest: PropTypes.func.isRequired,
handleDuplicateRequest: PropTypes.func.isRequired,
handleDuplicateRequestGroup: PropTypes.func.isRequired,

View File

@ -928,104 +928,50 @@ function mapDispatchToProps (dispatch) {
handleImportUriToWorkspace: global.importUri,
handleCommand: global.newCommand,
handleExportFile: global.exportFile,
handleMoveRequest: _moveRequest,
handleMoveRequestGroup: _moveRequestGroup
handleMoveDoc: _moveDoc
};
}
async function _moveRequestGroup (requestGroupToMove, requestGroupToTarget, targetOffset) {
// Oh God, this function is awful...
if (requestGroupToMove._id === requestGroupToTarget._id) {
// Nothing to do
return;
}
// NOTE: using requestToTarget's parentId so we can switch parents!
let requestGroups = await models.requestGroup.findByParentId(requestGroupToTarget.parentId);
requestGroups = requestGroups.sort((a, b) => a.metaSortKey < b.metaSortKey ? -1 : 1);
// Find the index of request B so we can re-order and save everything
for (let i = 0; i < requestGroups.length; i++) {
const request = requestGroups[i];
if (request._id === requestGroupToTarget._id) {
let before, after;
if (targetOffset < 0) {
// We're moving to below
before = requestGroups[i];
after = requestGroups[i + 1];
} else {
// We're moving to above
before = requestGroups[i - 1];
after = requestGroups[i];
}
const beforeKey = before ? before.metaSortKey : requestGroups[0].metaSortKey - 100;
const afterKey = after ? after.metaSortKey : requestGroups[requestGroups.length - 1].metaSortKey + 100;
if (Math.abs(afterKey - beforeKey) < 0.000001) {
// If sort keys get too close together, we need to redistribute the list. This is
// not performant at all (need to update all siblings in DB), but it is extremely rare
// anyway
console.log(`-- Recreating Sort Keys ${beforeKey} ${afterKey} --`);
db.bufferChanges(300);
requestGroups.map((r, i) => {
models.requestGroup.update(r, {
metaSortKey: i * 100,
parentId: requestGroupToTarget.parentId
});
});
} else {
const metaSortKey = afterKey - ((afterKey - beforeKey) / 2);
models.requestGroup.update(requestGroupToMove, {
metaSortKey,
parentId: requestGroupToTarget.parentId
});
}
break;
}
}
}
async function _moveRequest (requestToMove, parentId, targetId, targetOffset) {
// Oh God, this function is awful...
if (requestToMove._id === targetId) {
async function _moveDoc (docToMove, parentId, targetId, targetOffset) {
if (docToMove._id === targetId) {
// Nothing to do. We are in the same spot as we started
return;
}
function __updateDoc (doc, patch) {
models.getModel(docToMove.type).update(doc, patch);
}
if (targetId === null) {
// We are moving to an empty area. No sorting required
models.request.update(requestToMove, {parentId});
await __updateDoc(docToMove, {parentId});
return;
}
// NOTE: using requestToTarget's parentId so we can switch parents!
let requests = await models.request.findByParentId(parentId);
requests = requests.sort((a, b) => a.metaSortKey < b.metaSortKey ? -1 : 1);
let docs = [
...await models.request.findByParentId(parentId),
...await models.requestGroup.findByParentId(parentId)
].sort((a, b) => a.metaSortKey < b.metaSortKey ? -1 : 1);
// Find the index of request B so we can re-order and save everything
for (let i = 0; i < requests.length; i++) {
const request = requests[i];
// Find the index of doc B so we can re-order and save everything
for (let i = 0; i < docs.length; i++) {
const doc = docs[i];
if (request._id === targetId) {
if (doc._id === targetId) {
let before, after;
if (targetOffset < 0) {
// We're moving to below
before = requests[i];
after = requests[i + 1];
before = docs[i];
after = docs[i + 1];
} else {
// We're moving to above
before = requests[i - 1];
after = requests[i];
before = docs[i - 1];
after = docs[i];
}
const beforeKey = before ? before.metaSortKey : requests[0].metaSortKey - 100;
const afterKey = after ? after.metaSortKey : requests[requests.length - 1].metaSortKey + 100;
const beforeKey = before ? before.metaSortKey : docs[0].metaSortKey - 100;
const afterKey = after ? after.metaSortKey : docs[docs.length - 1].metaSortKey + 100;
if (Math.abs(afterKey - beforeKey) < 0.000001) {
// If sort keys get too close together, we need to redistribute the list. This is
@ -1034,12 +980,10 @@ async function _moveRequest (requestToMove, parentId, targetId, targetOffset) {
console.log(`-- Recreating Sort Keys ${beforeKey} ${afterKey} --`);
db.bufferChanges(300);
requests.map((r, i) => {
models.request.update(r, {metaSortKey: i * 100, parentId});
});
docs.map((r, i) => __updateDoc(r, {metaSortKey: i * 100, parentId}));
} else {
const metaSortKey = afterKey - ((afterKey - beforeKey) / 2);
models.request.update(requestToMove, {metaSortKey, parentId});
__updateDoc(docToMove, {metaSortKey, parentId});
}
break;

View File

@ -1,5 +1,4 @@
import {createSelector} from 'reselect';
import * as models from '../../models/index';
// ~~~~~~~~~ //
// Selectors //
@ -67,16 +66,6 @@ export const selectSidebarChildren = createSelector(
const children = requestsAndRequestGroups
.filter(e => e.parentId === parentId)
.sort((a, b) => {
// Always sort folders above
if (a.type === models.requestGroup.type && b.type !== models.requestGroup.type) {
return -1;
}
// Always sort folders above
if (b.type === models.requestGroup.type && a.type !== models.requestGroup.type) {
return 1;
}
if (a.metaSortKey === b.metaSortKey) {
return a._id > b._id ? -1 : 1;
} else {