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

232 lines
6.6 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-10 01:15:27 +00:00
import {DragSource, DropTarget} from 'react-dnd';
import classnames from 'classnames';
import RequestActionsDropdown from '../dropdowns/request-actions-dropdown';
import Editable from '../base/editable';
import MethodTag from '../tags/method-tag';
2016-11-10 05:56:23 +00:00
import * as models from '../../../models';
import {trackEvent} from '../../../analytics/index';
import {showModal} from '../modals/index';
import RequestSettingsModal from '../modals/request-settings-modal';
@autobind
2016-11-26 00:37:59 +00:00
class SidebarRequestRow extends PureComponent {
constructor (props) {
super(props);
this.state = {
dragDirection: 0,
isEditing: false
};
}
_setRequestActionsDropdownRef (n) {
this._requestActionsDropdown = n;
}
_handleShowRequestActions (e) {
e.preventDefault();
this._requestActionsDropdown.show();
}
_handleEditStart () {
trackEvent('Request', 'Rename', 'In Place');
this.setState({isEditing: true});
}
_handleRequestUpdateName (name) {
models.request.update(this.props.request, {name});
2017-01-24 00:48:28 +00:00
this.setState({isEditing: false});
}
2016-11-25 20:55:15 +00:00
_handleRequestCreateFromEmpty () {
2016-11-25 23:09:17 +00:00
const parentId = this.props.requestGroup._id;
this.props.requestCreate(parentId);
2016-11-25 20:55:15 +00:00
trackEvent('Request', 'Create', 'Empty Folder');
}
2016-11-25 20:55:15 +00:00
_handleRequestActivate () {
2016-11-25 20:55:15 +00:00
const {isActive, request, handleActivateRequest} = this.props;
if (isActive) {
return;
}
2016-11-25 20:55:15 +00:00
2016-11-25 23:09:17 +00:00
handleActivateRequest(request._id);
2016-11-25 20:55:15 +00:00
trackEvent('Request', 'Activate', 'Sidebar');
}
_handleShowRequestSettings () {
showModal(RequestSettingsModal, this.props.request);
}
setDragDirection (dragDirection) {
if (dragDirection !== this.state.dragDirection) {
this.setState({dragDirection});
}
2016-05-01 19:56:30 +00:00
}
render () {
const {
handleDuplicateRequest,
2016-11-28 07:12:17 +00:00
handleGenerateCode,
connectDragSource,
connectDropTarget,
isDragging,
isDraggingOver,
request,
requestGroup,
isActive
} = this.props;
const {dragDirection} = this.state;
let node;
const classes = classnames('sidebar__row', {
'sidebar__row--dragging': isDragging,
'sidebar__row--dragging-above': isDraggingOver && dragDirection > 0,
'sidebar__row--dragging-below': isDraggingOver && dragDirection < 0
});
if (!request) {
node = (
<li className={classes}>
2016-07-20 23:16:28 +00:00
<div className="sidebar__item" tabIndex={0}>
2017-06-02 00:00:57 +00:00
<button className="sidebar__clickable" onClick={this._handleRequestCreateFromEmpty}>
2017-01-23 22:41:31 +00:00
<em className="faded">click to add first request...</em>
</button>
2016-07-08 06:02:40 +00:00
</div>
</li>
);
} else {
node = (
<li className={classes}>
<div className={classnames('sidebar__item', 'sidebar__item--request', {
'sidebar__item--active': isActive
})}>
<button className="wide"
onClick={this._handleRequestActivate}
onContextMenu={this._handleShowRequestActions}>
<div className="sidebar__clickable">
<MethodTag method={request.method}/>
<div>
<Editable value={request.name}
className="inline-block"
onEditStart={this._handleEditStart}
onSubmit={this._handleRequestUpdateName}/>
{request.description && (
2017-06-02 00:25:36 +00:00
<span
title="Request has description"
className="space-left txt-sm super-duper-faint">
<i className="fa fa-file-text-o"/>
2017-06-02 00:25:36 +00:00
</span>
)}
</div>
</div>
</button>
<div className="sidebar__actions">
<RequestActionsDropdown
right
ref={this._setRequestActionsDropdownRef}
handleDuplicateRequest={handleDuplicateRequest}
2016-11-28 07:12:17 +00:00
handleGenerateCode={handleGenerateCode}
handleShowSettings={this._handleShowRequestSettings}
request={request}
requestGroup={requestGroup}
/>
</div>
</div>
</li>
);
}
if (!this.state.isEditing) {
return connectDragSource(connectDropTarget(node));
} else {
return connectDropTarget(node);
}
}
}
SidebarRequestRow.propTypes = {
// Functions
handleActivateRequest: PropTypes.func.isRequired,
handleDuplicateRequest: PropTypes.func.isRequired,
2016-11-28 07:12:17 +00:00
handleGenerateCode: PropTypes.func.isRequired,
requestCreate: PropTypes.func.isRequired,
moveRequest: PropTypes.func.isRequired,
2016-04-29 03:37:49 +00:00
// Other
isActive: PropTypes.bool.isRequired,
2016-04-29 03:37:49 +00:00
// React DnD
isDragging: PropTypes.bool,
isDraggingOver: PropTypes.bool,
connectDragSource: PropTypes.func,
connectDropTarget: PropTypes.func,
// Optional
requestGroup: PropTypes.object,
request: PropTypes.object
};
const dragSource = {
beginDrag (props) {
trackEvent('Request', 'Drag', 'Begin');
return {request: props.request};
}
};
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) {
const {request} = monitor.getItem();
const targetRequest = props.request;
const {requestGroup} = props;
const requestGroupId = requestGroup ? requestGroup._id : null;
const parentId = targetRequest ? targetRequest.parentId : requestGroupId;
const targetId = targetRequest ? targetRequest._id : null;
if (isAbove(monitor, component)) {
props.moveRequest(request, parentId, targetId, 1);
} else {
props.moveRequest(request, 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()
};
}
const source = DragSource('SIDEBAR_REQUEST_ROW', dragSource, sourceCollect)(SidebarRequestRow);
export default DropTarget('SIDEBAR_REQUEST_ROW', dragTarget, targetCollect)(source);