UNPKG

stitch-ui

Version:

188 lines (174 loc) 6.28 kB
import React from "react"; import PropTypes from "prop-types"; import { findDOMNode } from "react-dom"; import { DragSource, DropTarget } from "react-dnd"; import classNames from "classnames"; import { Button, Banner, DragHandle } from "../../core"; import { PipelineStage, PipelineStageEditState } from "../../models"; import PipelineStageEditor from "./PipelineStageEditor"; /* drag and drop boilerplate */ const stageSource = { beginDrag(props) { return { index: props.index }; } }; const stageTarget = { hover(props, monitor, component) { const dragIndex = monitor.getItem().index; const hoverIndex = props.index; if (dragIndex === hoverIndex) { return; } // eslint-disable-next-line react/no-find-dom-node const hoverBoundingRect = findDOMNode(component).getBoundingClientRect(); const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2; const clientOffset = monitor.getClientOffset(); const hoverClientY = clientOffset.y - hoverBoundingRect.top; if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) { return; } if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) { return; } component.props.moveToIndex(dragIndex); const item = monitor.getItem(); item.index = hoverIndex; } }; const collectDrag = (connect, monitor) => ({ connectDragSource: connect.dragSource(), connectDragPreview: connect.dragPreview(), isDragging: monitor.isDragging() }); const collectDrop = connect => ({ connectDropTarget: connect.dropTarget() }); class PipelineStageDisplay extends React.Component { constructor(props) { super(props); this.state = { editorOpen: false }; } render() { // drag/drop properties const { isDragging, connectDragSource, connectDragPreview, connectDropTarget } = this.props; // data properties const { services, stage, editState, removeStage, setStage, applyEditChange } = this.props; // editor actions const { openEditor, closeEditor } = this.props; return connectDropTarget( connectDragPreview( <div className={classNames("pipeline-editor-stage-container", { "pipeline-editor-stage-container-is-dragging": isDragging })} > <Banner message={stage.error} error /> <div className={classNames("pipeline-editor-stage", { "pipeline-editor-stage-is-dragging": isDragging })} > {connectDragSource( <div className={classNames("pipeline-editor-stage-draghandle", { "pipeline-editor-stage-draghandle-is-hidden": !!editState })} > <DragHandle /> </div> )} {editState ? <div className="pipeline-editor-stage-contents pipeline-editor-stage-contents-editing"> <PipelineStageEditor services={services} editState={editState} setStage={setStage} applyEditChange={applyEditChange} onClose={closeEditor} /> </div> : <div className="pipeline-editor-stage-contents"> <div className="pipeline-editor-stage-labelwrapper"> <div className="pipeline-editor-stage-label">Service</div> <div className="pipeline-editor-stage-label-text"> {stage.service || "built-in"} </div> </div> <div className="pipeline-editor-stage-labelwrapper"> <div className="pipeline-editor-stage-label">Action</div> <div className="pipeline-editor-stage-label-text"> {stage.action} </div> </div> <div className="pipeline-editor-stage-labelwrapper pipeline-editor-stage-labelwrapper-args"> <div className="pipeline-editor-stage-label">Args</div> <div className="pipeline-editor-stage-label-text pipeline-editor-stage-label-text-is-mono"> {JSON.stringify(stage.args)} </div> {stage.let && <div className="pipeline-editor-stage-label"> let </div>} {stage.let && <div className="pipeline-editor-stage-label-text pipeline-editor-stage-label-text-is-mono"> {JSON.stringify(stage.let)} </div>} </div> </div>} <div className="pipeline-editor-stage-controls"> <Button small onClick={openEditor}> <i className="fa fa-pencil-square-o" /> Edit </Button> <Button small onClick={removeStage}> <i className="fa fa-trash" /> Delete </Button> </div> </div> <div className="pipeline-editor-downarrow"> <i className="fa fa-long-arrow-down" /> </div> </div> ) ); } } export default DragSource("stage", stageSource, collectDrag)( DropTarget("stage", stageTarget, collectDrop)(PipelineStageDisplay) ); PipelineStageDisplay.propTypes = { isDragging: PropTypes.bool, connectDragSource: PropTypes.func, connectDragPreview: PropTypes.func, connectDropTarget: PropTypes.func, services: PropTypes.objectOf( PropTypes.shape({ type: PropTypes.string.isRequired, config: PropTypes.object, rules: PropTypes.object.isRequired }) ).isRequired, stage: PropTypes.instanceOf(PipelineStage).isRequired, editState: PropTypes.instanceOf(PipelineStageEditState), removeStage: PropTypes.func.isRequired, setStage: PropTypes.func.isRequired, applyEditChange: PropTypes.func.isRequired, openEditor: PropTypes.func.isRequired, closeEditor: PropTypes.func.isRequired }; PipelineStageDisplay.defaultProps = { isDragging: false, connectDragSource: x => x, connectDragPreview: x => x, connectDropTarget: x => x, editState: null };