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

205 lines
5.9 KiB
JavaScript
Raw Normal View History

2016-11-26 00:37:59 +00:00
import React, {PropTypes, PureComponent} from 'react';
import autobind from 'autobind-decorator';
import ReactDOM from 'react-dom';
2016-11-25 23:09:17 +00:00
import {DragSource, DropTarget} from 'react-dnd';
import classnames from 'classnames';
import RequestGroupActionsDropdown from '../dropdowns/request-group-actions-dropdown';
import SidebarRequestRow from './sidebar-request-row';
import {trackEvent} from '../../../analytics/index';
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 {
constructor (props) {
super(props);
this.state = {
dragDirection: 0
};
}
_setRequestGroupActionsDropdownRef (n) {
this._requestGroupActionsDropdown = n;
}
_handleCollapse () {
2016-11-25 20:55:15 +00:00
const {requestGroup, handleSetRequestGroupCollapsed, isCollapsed} = this.props;
handleSetRequestGroupCollapsed(requestGroup._id, !isCollapsed);
trackEvent('Folder', 'Toggle Visible', !isCollapsed ? 'Close' : 'Open');
}
2016-11-25 20:55:15 +00:00
_handleShowActions (e) {
e.preventDefault();
this._requestGroupActionsDropdown.show();
}
setDragDirection (dragDirection) {
if (dragDirection !== this.state.dragDirection) {
this.setState({dragDirection});
}
}
render () {
const {
connectDragSource,
connectDropTarget,
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,
isDragging,
isDraggingOver,
workspace
} = this.props;
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)
const button = connectDragSource(connectDropTarget(
<button onClick={this._handleCollapse} onContextMenu={this._handleShowActions}>
2017-01-24 00:48:28 +00:00
<div className="sidebar__clickable">
2017-07-25 22:28:53 +00:00
<i className={'sidebar__item__icon fa ' + folderIconClass}/>
2017-01-24 00:48:28 +00:00
<span>{requestGroup.name}</span>
</div>
</button>
));
return (
<li key={requestGroup._id} className={classes}>
2017-01-24 00:48:28 +00:00
<div className={classnames(
'sidebar__item sidebar__item--big', {'sidebar__item--active': isActive}
)}>
{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}
workspace={workspace}
requestGroup={requestGroup}
right
/>
</div>
2016-04-29 03:37:49 +00:00
</div>
2016-11-26 00:37:59 +00:00
<ul className={classnames('sidebar__list', {'sidebar__list--collapsed': isCollapsed})}>
2016-11-26 08:29:16 +00:00
{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}
2017-06-13 20:45:15 +00:00
moveDoc={moveDoc}
isActive={false}
request={null}
requestGroup={requestGroup}
workspace={workspace}
requestCreate={handleCreateRequest}
/>
)}
</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,
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
isActive: PropTypes.bool.isRequired,
isCollapsed: PropTypes.bool.isRequired,
workspace: PropTypes.object.isRequired,
2016-11-25 20:55:15 +00:00
requestGroup: PropTypes.object.isRequired,
// React DnD
isDragging: PropTypes.bool,
isDraggingOver: PropTypes.bool,
connectDragSource: PropTypes.func,
connectDropTarget: PropTypes.func,
// Optional
children: PropTypes.node
};
/**
* Implements the drag source contract.
*/
const dragSource = {
beginDrag (props) {
trackEvent('Folder', 'Drag', 'Begin');
return {
requestGroup: props.requestGroup
};
}
};
function isAbove (monitor, component) {
const hoveredNode = ReactDOM.findDOMNode(component);
const hoveredTop = hoveredNode.getBoundingClientRect().top;
const draggedTop = monitor.getSourceClientOffset().y;
return hoveredTop > draggedTop;
}
const dragTarget = {
drop (props, monitor, component) {
2017-06-13 20:45:15 +00:00
const movingDoc = monitor.getItem().requestGroup || monitor.getItem().request;
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);
}
},
hover (props, monitor, component) {
if (isAbove(monitor, component)) {
component.decoratedComponentInstance.setDragDirection(1);
} else {
component.decoratedComponentInstance.setDragDirection(-1);
}
}
};
function sourceCollect (connect, monitor) {
return {
connectDragSource: connect.dragSource(),
isDragging: monitor.isDragging()
};
}
function targetCollect (connect, monitor) {
return {
connectDropTarget: connect.dropTarget(),
isDraggingOver: monitor.isOver()
};
}
2017-06-13 20:45:15 +00:00
const source = DragSource('SIDEBAR_REQUEST_ROW', dragSource, sourceCollect)(SidebarRequestGroupRow);
export default DropTarget('SIDEBAR_REQUEST_ROW', dragTarget, targetCollect)(source);