diff --git a/package.json b/package.json index cd694136..c66dd0d4 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,6 @@ "redux": "^1.0.0 || 1.0.0-rc" }, "dependencies": { - "lodash.assign": "^3.2.0", "react-mixin": "^1.7.0", "react-redux": "^0.2.2", "redux": "^1.0.0-rc" diff --git a/src/react/DebugPanel.js b/src/react/DebugPanel.js index c87fff6c..c81a91f9 100644 --- a/src/react/DebugPanel.js +++ b/src/react/DebugPanel.js @@ -13,9 +13,9 @@ export function getDefaultStyle(props) { position: 'fixed', zIndex: 999, fontSize: 17, - overflow: 'auto', + overflow: 'hidden', opacity: 0.92, - background: 'black', + background: '#181d20', color: 'white', left: left ? 0 : undefined, right: right ? 0 : undefined, @@ -23,7 +23,9 @@ export function getDefaultStyle(props) { bottom: bottom ? 0 : undefined, maxHeight: (bottom && top) ? '100%' : '20%', maxWidth: (left && right) ? '100%' : '20%', - wordWrap: 'break-word' + minWidth: 260, + wordWrap: 'break-word', + boxSizing: 'border-box' }; } diff --git a/src/react/JSONTree/JSONArrayNode.js b/src/react/JSONTree/JSONArrayNode.js index 1b1e305c..e7075453 100644 --- a/src/react/JSONTree/JSONArrayNode.js +++ b/src/react/JSONTree/JSONArrayNode.js @@ -3,7 +3,6 @@ import reactMixin from 'react-mixin'; import { ExpandedStateHandlerMixin } from './mixins'; import JSONArrow from './JSONArrow'; import grabNode from './grab-node'; -import assign from 'lodash.assign'; const styles = { base: { @@ -90,8 +89,14 @@ export default class JSONArrayNode extends React.Component { listStyle: 'none', display: (this.state.expanded) ? 'block' : 'none' }; - let containerStyle = assign({}, styles.base, styles.parentNode); - let spanStyle = assign({}, styles.span, this.state.expanded ? styles.spanExpanded : {}); + let containerStyle = {...styles.base, ...styles.parentNode}; + let spanStyle = { ...styles.span }; + if (this.state.expanded) { + spanStyle = { + ...spanStyle, + ...styles.spanExpanded + }; + } return (
  • diff --git a/src/react/JSONTree/JSONArrow.js b/src/react/JSONTree/JSONArrow.js index c7df7871..6a18cc37 100644 --- a/src/react/JSONTree/JSONArrow.js +++ b/src/react/JSONTree/JSONArrow.js @@ -1,5 +1,4 @@ import React from 'react'; -import assign from 'lodash.assign'; const styles = { base: { @@ -26,7 +25,13 @@ const styles = { export default class JSONArrow extends React.Component { render() { - const style = assign({}, styles.base, this.props.open ? styles.open : {}); + let style = { ...styles.base }; + if (this.props.open) { + style = { + ...style, + ...styles.open + }; + } return
    ; } } diff --git a/src/react/JSONTree/JSONObjectNode.js b/src/react/JSONTree/JSONObjectNode.js index b86ad962..9adaf263 100644 --- a/src/react/JSONTree/JSONObjectNode.js +++ b/src/react/JSONTree/JSONObjectNode.js @@ -2,7 +2,6 @@ import React from 'react'; import reactMixin from 'react-mixin'; import { ExpandedStateHandlerMixin } from './mixins'; import JSONArrow from './JSONArrow'; -import assign from 'lodash.assign'; import grabNode from './grab-node'; const styles = { @@ -92,8 +91,14 @@ export default class JSONObjectNode extends React.Component { listStyle: 'none', display: (this.state.expanded) ? 'block' : 'none' }; - let containerStyle = assign({}, styles.base, styles.parentNode); - let spanStyle = assign({}, styles.span, this.state.expanded ? styles.spanExpanded : {}); + let containerStyle = {...styles.base, ...styles.parentNode}; + let spanStyle = { ...styles.span }; + if (this.state.expanded) { + spanStyle = { + ...spanStyle, + ...styles.spanExpanded + }; + } return (
  • diff --git a/src/react/JSONTree/index.js b/src/react/JSONTree/index.js index 9808ad33..f40005cd 100644 --- a/src/react/JSONTree/index.js +++ b/src/react/JSONTree/index.js @@ -13,9 +13,9 @@ const styles = { border: 0, padding: 0, margin: 0, - fontSize: 14, + fontSize: '0.90em', listStyle: 'none', - fontFamily: '"Helvetica Neue", Helvetica, Arial, freesans, sans-serif', + fontFamily: 'monospace', MozUserSelect: 'none', WebkitUserSelect: 'none' } @@ -36,10 +36,11 @@ export default class JSONTree extends React.Component { render() { const nodeType = objectType(this.props.data); let rootNode = false; + const keyName = this.props.keyName || 'root'; if (nodeType === 'Object') { - rootNode = ; + rootNode = ; } else if (nodeType === 'Array') { - rootNode = ; + rootNode = ; } return (
      diff --git a/src/react/LogMonitor.js b/src/react/LogMonitor.js index 99691c9b..28954757 100644 --- a/src/react/LogMonitor.js +++ b/src/react/LogMonitor.js @@ -1,5 +1,28 @@ import React, { PropTypes, findDOMNode } from 'react'; import LogMonitorEntry from './LogMonitorEntry'; +import LogMonitorButton from './LogMonitorButton'; + +const styles = { + container: { + fontFamily: 'monospace', + position: 'relative', + overflowY: 'hidden' + }, + buttonBarWrapper: { + backgroundColor: '#343c45', + borderBottom: '1px solid #3f464d', + marginBottom: 1 + }, + buttonBar: { + paddingLeft: 2 + }, + bordering: { + 'float': 'left', + height: 1, + border: '1px solid #20262c', + width: '100%' + } +} export default class LogMonitor { constructor() { @@ -24,11 +47,11 @@ export default class LogMonitor { static defaultProps = { select: (state) => state, - monitorState: { isVisible: true } + monitorState: { isVisible: true }, }; componentWillReceiveProps(nextProps) { - const node = findDOMNode(this); + const node = findDOMNode(this.refs.elements); if (!node) { this.scrollDown = true; } else if ( @@ -46,7 +69,7 @@ export default class LogMonitor { } componentDidUpdate() { - const node = findDOMNode(this); + const node = findDOMNode(this.refs.elements); if (!node) { return; } @@ -95,7 +118,6 @@ export default class LogMonitor { render() { const elements = []; const { monitorState, skippedActions, stagedActions, computedStates, select } = this.props; - if (!monitorState.isVisible) { return null; } @@ -117,52 +139,26 @@ export default class LogMonitor { } return ( -
      -
      -
      - Press Ctrl+H to hide. -
      -
      - - Reset - +
      +
      +
      + Reset + {computedStates.length > 1 && + Revert + } + {Object.keys(skippedActions).some(key => skippedActions[key]) && + Sweep + } + {computedStates.length > 1 && + Commit + }
      - {elements} -
      - {computedStates.length > 1 && - - Rollback - - } - {Object.keys(skippedActions).some(key => skippedActions[key]) && - - {' • '} - - Sweep - - - } - {computedStates.length > 1 && - - - {' • '} - - - Commit - - - } +
      + {elements}
      ); diff --git a/src/react/LogMonitorButton.js b/src/react/LogMonitorButton.js new file mode 100644 index 00000000..e1831000 --- /dev/null +++ b/src/react/LogMonitorButton.js @@ -0,0 +1,63 @@ +import React from 'react'; + +const styles = { + base: { + paddingTop: 3, + paddingBottom: 3, + paddingLeft: 6, + paddingRight: 6, + marginTop: 2, + display: 'inline-block', + fontSize: "0.8em" + }, + active: { + backgroundColor: "#252c33" + } +} + +export default class LogMonitorButton extends React.Component { + constructor(props) { + super(props); + this.state = { + hovered: false, + active: false + } + } + + handleMouseEnter() { + this.setState({ hovered: true }); + } + + handleMouseLeave() { + this.setState({ hovered: false }); + } + + handleMouseDown() { + this.setState({ active: true }); + } + + handleMouseUp() { + this.setState({ active: false }); + } + + render() { + let style = { + ...styles.base, + }; + if (this.state.hovered) { + style = { + ...style, + ...styles.active + }; + } + return ( + + {this.props.children} + + ); + } +} diff --git a/src/react/LogMonitorEntry.js b/src/react/LogMonitorEntry.js index e8bb4377..bb47b3be 100644 --- a/src/react/LogMonitorEntry.js +++ b/src/react/LogMonitorEntry.js @@ -1,5 +1,6 @@ import React, { PropTypes } from 'react'; import JSONTree from './JSONTree'; +import LogMonitorEntryAction from "./LogMonitorEntryAction"; function hsvToRgb(h, s, v) { const i = Math.floor(h); @@ -35,6 +36,13 @@ function colorFromString(token) { return hsvToRgb(h, s, v); } +const styles = { + entry: { + display: 'block', + WebkitUserSelect: 'none' + } +}; + export default class LogMonitorEntry { static propTypes = { index: PropTypes.number.isRequired, @@ -50,14 +58,14 @@ export default class LogMonitorEntry { let errorText = error; if (!errorText) { try { - return + return } catch (err) { errorText = 'Error selecting state.'; } } - return ( ({errorText}) @@ -73,49 +81,24 @@ export default class LogMonitorEntry { } render() { - const { index, error, action, state, collapsed } = this.props; - const { r, g, b } = colorFromString(action.type); - - return ( -
      - 0) ? 'pointer' : 'default', - WebkitUserSelect: 'none' - }}> - {JSON.stringify(action)} - - - {!collapsed && -

      - ⇧ -

      - } - - {!collapsed && -
      - {this.printState(state, error)} -
      - } - -
      + const { index, error, action, state, collapsed } = this.props; + const { r, g, b } = colorFromString(action.type); + const styleEntry = { + opacity: collapsed ? 0.5 : 1, + color: `rgb(${r}, ${g}, ${b})`, + cursor: (index > 0) ? 'pointer' : 'default' + }; + return ( +
      + + {!collapsed && +
      + {this.printState(state, error)} +
      + }
      ); } diff --git a/src/react/LogMonitorEntryAction.js b/src/react/LogMonitorEntryAction.js new file mode 100644 index 00000000..48911304 --- /dev/null +++ b/src/react/LogMonitorEntryAction.js @@ -0,0 +1,38 @@ +import React from "react"; +import JSONTree from './JSONTree'; + +const styles = { + wrapper: { + backgroundColor: '#343c45', + borderTop: '1px solid #3f464d', + borderBottom: '1px solid #3f464d' + }, + actionBar: { + paddingTop: 4, + paddingBottom: 4, + paddingLeft: 10, + marginBottom: 1 + }, + payload: { + backgroundColor: '#252c33', + paddingLeft: 15 + } +} +export default class LogMonitorAction extends React.Component { + renderPayload(payload) { + return ( +
      + { Object.keys(payload).length > 0 ? : "" } +
      + ); + } + render() { + const { type, ...payload } = this.props.action; + return ( +
      +
      {type}
      + {!this.props.collapsed ? '' : ''} +
      + ); + } +} \ No newline at end of file