insomnia/packages/insomnia-app/app/ui/components/sidebar/sidebar-request-group-row.js

265 lines
7.6 KiB
JavaScript
Raw Normal View History

2018-06-25 17:42:50 +00:00
import React, { PureComponent } from 'react';
2017-08-10 01:56:27 +00:00
import PropTypes from 'prop-types';
import autobind from 'autobind-decorator';
import ReactDOM from 'react-dom';
2018-06-25 17:42:50 +00:00
import { DragSource, DropTarget } from 'react-dnd';
import classnames from 'classnames';
import Highlight from '../base/highlight';
import RequestGroupActionsDropdown from '../dropdowns/request-group-actions-dropdown';
import SidebarRequestRow from './sidebar-request-row';
import * as misc from '../../../common/misc';
2016-05-01 19:56:30 +00:00
@autobind
2016-11-26 00:37:59 +00:00
class SidebarRequestGroupRow extends PureComponent {
2018-06-25 17:42:50 +00:00
constructor(props) {
super(props);
this.state = {
dragDirection: 0,
};
}
2018-06-25 17:42:50 +00:00
_setRequestGroupActionsDropdownRef(n) {
this._requestGroupActionsDropdown = n;
}
_setExpandTagRef(n) {
this._expandTag = n;
}
getExpandTag() {
return this._expandTag;
}
2018-06-25 17:42:50 +00:00
_handleCollapse() {
2018-10-17 16:42:33 +00:00
const { requestGroup, handleSetRequestGroupCollapsed, isCollapsed } = this.props;
2016-11-25 20:55:15 +00:00
handleSetRequestGroupCollapsed(requestGroup._id, !isCollapsed);
}
2016-11-25 20:55:15 +00:00
2018-06-25 17:42:50 +00:00
_handleShowActions(e) {
e.preventDefault();
this._requestGroupActionsDropdown.show();
}
2018-06-25 17:42:50 +00:00
setDragDirection(dragDirection) {
if (dragDirection !== this.state.dragDirection) {
2018-06-25 17:42:50 +00:00
this.setState({ dragDirection });
}
}
2018-06-25 17:42:50 +00:00
render() {
const {
connectDragSource,
connectDropTarget,
filter,
2017-06-13 20:45:15 +00:00
moveDoc,
children,
requestGroup,
isCollapsed,
isActive,
handleCreateRequest,
2016-11-23 20:44:46 +00:00
handleCreateRequestGroup,
2016-11-28 07:12:17 +00:00
handleDuplicateRequestGroup,
handleMoveRequestGroup,
isDragging,
isDraggingOver,
workspace,
hotKeyRegistry,
activeEnvironment,
} = this.props;
2018-06-25 17:42:50 +00:00
const { dragDirection } = this.state;
let folderIconClass = 'fa-folder';
folderIconClass += isCollapsed ? '' : '-open';
folderIconClass += isActive ? '' : '-o';
const classes = classnames('sidebar__row', {
'sidebar__row--dragging': isDragging,
'sidebar__row--dragging-above': isDraggingOver && dragDirection > 0,
'sidebar__row--dragging-below': isDraggingOver && dragDirection < 0,
});
2017-01-24 00:48:28 +00:00
// NOTE: We only want the button draggable, not the whole container (ie. no children)
2018-06-25 17:42:50 +00:00
const button = connectDragSource(
connectDropTarget(
2018-10-17 16:42:33 +00:00
<button onClick={this._handleCollapse} onContextMenu={this._handleShowActions}>
2018-06-25 17:42:50 +00:00
<div className="sidebar__clickable">
2019-05-07 15:10:13 +00:00
<i
className={classnames(
'sidebar__item__icon-right',
'fa',
'space-right',
folderIconClass,
)}
/>
2018-06-25 17:42:50 +00:00
<Highlight search={filter} text={requestGroup.name} />
<div
ref={this._setExpandTagRef}
className={classnames('sidebar__expand', {
'sidebar__expand-hint': isDraggingOver && isCollapsed,
})}>
<div className="tag tag--no-bg tag--small">
<span className="tag__inner">OPEN</span>
</div>
</div>
2018-06-25 17:42:50 +00:00
</div>
</button>,
),
2018-06-25 17:42:50 +00:00
);
2017-01-24 00:48:28 +00:00
return (
<li key={requestGroup._id} className={classes}>
2018-06-25 17:42:50 +00:00
<div
className={classnames('sidebar__item sidebar__item--big', {
'sidebar__item--active': isActive,
2018-06-25 17:42:50 +00:00
})}>
2017-01-24 00:48:28 +00:00
{button}
<div className="sidebar__actions">
<RequestGroupActionsDropdown
ref={this._setRequestGroupActionsDropdownRef}
2016-11-23 20:44:46 +00:00
handleCreateRequest={handleCreateRequest}
handleCreateRequestGroup={handleCreateRequestGroup}
2016-11-28 07:12:17 +00:00
handleDuplicateRequestGroup={handleDuplicateRequestGroup}
handleMoveRequestGroup={handleMoveRequestGroup}
workspace={workspace}
requestGroup={requestGroup}
hotKeyRegistry={hotKeyRegistry}
activeEnvironment={activeEnvironment}
right
/>
</div>
2016-04-29 03:37:49 +00:00
</div>
2018-06-25 17:42:50 +00:00
<ul
className={classnames('sidebar__list', {
'sidebar__list--collapsed': isCollapsed,
2018-06-25 17:42:50 +00:00
})}>
{!isCollapsed && children.length > 0 ? (
children
) : (
2017-06-13 20:45:15 +00:00
<SidebarRequestRow
handleActivateRequest={misc.nullFn}
handleDuplicateRequest={misc.nullFn}
handleGenerateCode={misc.nullFn}
handleCopyAsCurl={misc.nullFn}
handleSetRequestPinned={misc.nullFn}
2017-06-13 20:45:15 +00:00
moveDoc={moveDoc}
isActive={false}
request={null}
requestGroup={requestGroup}
workspace={workspace}
requestCreate={handleCreateRequest}
2018-05-23 07:07:22 +00:00
filter={filter}
hotKeyRegistry={hotKeyRegistry}
isPinned={false}
2017-06-13 20:45:15 +00:00
/>
)}
</ul>
</li>
2017-01-24 00:48:28 +00:00
);
}
}
SidebarRequestGroupRow.propTypes = {
// Functions
handleSetRequestGroupCollapsed: PropTypes.func.isRequired,
2016-11-28 07:12:17 +00:00
handleDuplicateRequestGroup: PropTypes.func.isRequired,
handleMoveRequestGroup: PropTypes.func.isRequired,
2017-06-13 20:45:15 +00:00
moveDoc: PropTypes.func.isRequired,
handleActivateRequest: PropTypes.func.isRequired,
handleCreateRequest: PropTypes.func.isRequired,
handleCreateRequestGroup: PropTypes.func.isRequired,
2016-04-29 03:37:49 +00:00
// Other
filter: PropTypes.string.isRequired,
isActive: PropTypes.bool.isRequired,
isCollapsed: PropTypes.bool.isRequired,
workspace: PropTypes.object.isRequired,
2016-11-25 20:55:15 +00:00
requestGroup: PropTypes.object.isRequired,
hotKeyRegistry: PropTypes.object.isRequired,
// React DnD
isDragging: PropTypes.bool,
isDraggingOver: PropTypes.bool,
connectDragSource: PropTypes.func,
connectDropTarget: PropTypes.func,
// Optional
children: PropTypes.node,
activeEnvironment: PropTypes.object,
};
/**
* Implements the drag source contract.
*/
const dragSource = {
2018-06-25 17:42:50 +00:00
beginDrag(props) {
return {
requestGroup: props.requestGroup,
};
},
};
2018-06-25 17:42:50 +00:00
function isAbove(monitor, component) {
const hoveredNode = ReactDOM.findDOMNode(component);
const hoveredTop = hoveredNode.getBoundingClientRect().top;
const draggedTop = monitor.getSourceClientOffset().y;
return hoveredTop > draggedTop;
}
function isOnExpandTag(monitor, component) {
const rect = component.getExpandTag().getBoundingClientRect();
const pointer = monitor.getClientOffset();
return (
rect.left <= pointer.x &&
pointer.x <= rect.right &&
rect.top <= pointer.y &&
pointer.y <= rect.bottom
);
}
const dragTarget = {
2018-06-25 17:42:50 +00:00
drop(props, monitor, component) {
2018-10-17 16:42:33 +00:00
const movingDoc = monitor.getItem().requestGroup || monitor.getItem().request;
2017-06-13 20:45:15 +00:00
const parentId = props.requestGroup.parentId;
const targetId = props.requestGroup._id;
if (isAbove(monitor, component)) {
2017-06-13 20:45:15 +00:00
props.moveDoc(movingDoc, parentId, targetId, 1);
} else {
2017-06-13 20:45:15 +00:00
props.moveDoc(movingDoc, parentId, targetId, -1);
}
},
2018-06-25 17:42:50 +00:00
hover(props, monitor, component) {
if (props.isCollapsed && isOnExpandTag(monitor, component)) {
component.props.handleSetRequestGroupCollapsed(props.requestGroup._id, false);
component.setDragDirection(0);
} else if (isAbove(monitor, component)) {
Version Control (beta) (#1439) * VCS proof of concept underway! * Stuff * Some things * Replace deprecated Electron makeSingleInstance * Rename `window` variables so not to be confused with window object * Don't unnecessarily update request when URL does not change * Regenerate package-lock * Fix tests + ESLint * Publish - insomnia-app@1.0.49 - insomnia-cookies@0.0.12 - insomnia-httpsnippet@1.16.18 - insomnia-importers@2.0.13 - insomnia-libcurl@0.0.23 - insomnia-prettify@0.1.7 - insomnia-url@0.1.6 - insomnia-xpath@1.0.9 - insomnia-plugin-base64@1.0.6 - insomnia-plugin-cookie-jar@1.0.8 - insomnia-plugin-core-themes@1.0.5 - insomnia-plugin-default-headers@1.1.9 - insomnia-plugin-file@1.0.7 - insomnia-plugin-hash@1.0.7 - insomnia-plugin-jsonpath@1.0.12 - insomnia-plugin-now@1.0.11 - insomnia-plugin-os@1.0.13 - insomnia-plugin-prompt@1.1.9 - insomnia-plugin-request@1.0.18 - insomnia-plugin-response@1.0.16 - insomnia-plugin-uuid@1.0.10 * Broken but w/e * Some tweaks * Big refactor. Create local snapshots and push done * POC merging and a lot of improvements * Lots of work done on initial UI/UX * Fix old tests * Atomic writes and size-based batches * Update StageEntry definition once again to be better * Factor out GraphQL query logic * Merge algorithm, history modal, other minor things * Fix test * Merge, checkout, revert w/ user changes now work * Force UI to refresh when switching branches changes active request * Rough draft pull() and some cleanup * E2EE stuff and some refactoring * Add ability to share project with team and fixed tests * VCS now created in root component and better remote project handling * Remove unused definition * Publish - insomnia-account@0.0.2 - insomnia-app@1.1.1 - insomnia-cookies@0.0.14 - insomnia-httpsnippet@1.16.20 - insomnia-importers@2.0.15 - insomnia-libcurl@0.0.25 - insomnia-prettify@0.1.9 - insomnia-sync@0.0.2 - insomnia-url@0.1.8 - insomnia-xpath@1.0.11 - insomnia-plugin-base64@1.0.8 - insomnia-plugin-cookie-jar@1.0.10 - insomnia-plugin-core-themes@1.0.7 - insomnia-plugin-file@1.0.9 - insomnia-plugin-hash@1.0.9 - insomnia-plugin-jsonpath@1.0.14 - insomnia-plugin-now@1.0.13 - insomnia-plugin-os@1.0.15 - insomnia-plugin-prompt@1.1.11 - insomnia-plugin-request@1.0.20 - insomnia-plugin-response@1.0.18 - insomnia-plugin-uuid@1.0.12 * Move some deps around * Fix Flow errors * Update package.json * Fix eslint errors * Fix tests * Update deps * bootstrap insomnia-sync * TRy fixing appveyor * Try something else * Bump lerna * try powershell * Try again * Fix imports * Fixed errors * sync types refactor * Show remote projects in workspace dropdown * Improved pulling of non-local workspaces * Loading indicators and some tweaks * Clean up sync staging modal * Some sync improvements: - No longer store stage - Upgrade Electron - Sync UI/UX improvements * Fix snyc tests * Upgraded deps and hot loader tweaks (it's broken for some reason) * Fix tests * Branches dialog, network refactoring, some tweaks * Fixed merging when other branch is empty * A bunch of small fixes from real testing * Fixed pull merge logic * Fix tests * Some bug fixes * A few small tweaks * Conflict resolution and other improvements * Fix tests * Add revert changes * Deal with duplicate projects per workspace * Some tweaks and accessibility improvements * Tooltip accessibility * Fix API endpoint * Fix tests * Remove jest dep from insomnia-importers
2019-04-18 00:50:03 +00:00
component.setDragDirection(1);
} else {
Version Control (beta) (#1439) * VCS proof of concept underway! * Stuff * Some things * Replace deprecated Electron makeSingleInstance * Rename `window` variables so not to be confused with window object * Don't unnecessarily update request when URL does not change * Regenerate package-lock * Fix tests + ESLint * Publish - insomnia-app@1.0.49 - insomnia-cookies@0.0.12 - insomnia-httpsnippet@1.16.18 - insomnia-importers@2.0.13 - insomnia-libcurl@0.0.23 - insomnia-prettify@0.1.7 - insomnia-url@0.1.6 - insomnia-xpath@1.0.9 - insomnia-plugin-base64@1.0.6 - insomnia-plugin-cookie-jar@1.0.8 - insomnia-plugin-core-themes@1.0.5 - insomnia-plugin-default-headers@1.1.9 - insomnia-plugin-file@1.0.7 - insomnia-plugin-hash@1.0.7 - insomnia-plugin-jsonpath@1.0.12 - insomnia-plugin-now@1.0.11 - insomnia-plugin-os@1.0.13 - insomnia-plugin-prompt@1.1.9 - insomnia-plugin-request@1.0.18 - insomnia-plugin-response@1.0.16 - insomnia-plugin-uuid@1.0.10 * Broken but w/e * Some tweaks * Big refactor. Create local snapshots and push done * POC merging and a lot of improvements * Lots of work done on initial UI/UX * Fix old tests * Atomic writes and size-based batches * Update StageEntry definition once again to be better * Factor out GraphQL query logic * Merge algorithm, history modal, other minor things * Fix test * Merge, checkout, revert w/ user changes now work * Force UI to refresh when switching branches changes active request * Rough draft pull() and some cleanup * E2EE stuff and some refactoring * Add ability to share project with team and fixed tests * VCS now created in root component and better remote project handling * Remove unused definition * Publish - insomnia-account@0.0.2 - insomnia-app@1.1.1 - insomnia-cookies@0.0.14 - insomnia-httpsnippet@1.16.20 - insomnia-importers@2.0.15 - insomnia-libcurl@0.0.25 - insomnia-prettify@0.1.9 - insomnia-sync@0.0.2 - insomnia-url@0.1.8 - insomnia-xpath@1.0.11 - insomnia-plugin-base64@1.0.8 - insomnia-plugin-cookie-jar@1.0.10 - insomnia-plugin-core-themes@1.0.7 - insomnia-plugin-file@1.0.9 - insomnia-plugin-hash@1.0.9 - insomnia-plugin-jsonpath@1.0.14 - insomnia-plugin-now@1.0.13 - insomnia-plugin-os@1.0.15 - insomnia-plugin-prompt@1.1.11 - insomnia-plugin-request@1.0.20 - insomnia-plugin-response@1.0.18 - insomnia-plugin-uuid@1.0.12 * Move some deps around * Fix Flow errors * Update package.json * Fix eslint errors * Fix tests * Update deps * bootstrap insomnia-sync * TRy fixing appveyor * Try something else * Bump lerna * try powershell * Try again * Fix imports * Fixed errors * sync types refactor * Show remote projects in workspace dropdown * Improved pulling of non-local workspaces * Loading indicators and some tweaks * Clean up sync staging modal * Some sync improvements: - No longer store stage - Upgrade Electron - Sync UI/UX improvements * Fix snyc tests * Upgraded deps and hot loader tweaks (it's broken for some reason) * Fix tests * Branches dialog, network refactoring, some tweaks * Fixed merging when other branch is empty * A bunch of small fixes from real testing * Fixed pull merge logic * Fix tests * Some bug fixes * A few small tweaks * Conflict resolution and other improvements * Fix tests * Add revert changes * Deal with duplicate projects per workspace * Some tweaks and accessibility improvements * Tooltip accessibility * Fix API endpoint * Fix tests * Remove jest dep from insomnia-importers
2019-04-18 00:50:03 +00:00
component.setDragDirection(-1);
}
},
};
2018-06-25 17:42:50 +00:00
function sourceCollect(connect, monitor) {
return {
connectDragSource: connect.dragSource(),
isDragging: monitor.isDragging(),
};
}
2018-06-25 17:42:50 +00:00
function targetCollect(connect, monitor) {
return {
connectDropTarget: connect.dropTarget(),
isDraggingOver: monitor.isOver(),
};
}
2018-10-17 16:42:33 +00:00
const source = DragSource('SIDEBAR_REQUEST_ROW', dragSource, sourceCollect)(SidebarRequestGroupRow);
export default DropTarget('SIDEBAR_REQUEST_ROW', dragTarget, targetCollect)(source);