diff --git a/package.json b/package.json index c7deebe026..999bdfb379 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ "redux": "^1.0.0 || 1.0.0-rc" }, "dependencies": { + "react-json-tree": "^0.1.1", "react-mixin": "^1.7.0", "react-redux": "^0.9.0", "redux": "^1.0.1" diff --git a/src/react/JSONTree/JSONArrayNode.js b/src/react/JSONTree/JSONArrayNode.js deleted file mode 100644 index 01012c0b85..0000000000 --- a/src/react/JSONTree/JSONArrayNode.js +++ /dev/null @@ -1,125 +0,0 @@ -import React from 'react'; -import reactMixin from 'react-mixin'; -import { ExpandedStateHandlerMixin } from './mixins'; -import JSONArrow from './JSONArrow'; -import grabNode from './grab-node'; - -const styles = { - base: { - position: 'relative', - paddingTop: 3, - paddingBottom: 3, - paddingRight: 0, - marginLeft: 14 - }, - label: { - margin: 0, - padding: 0, - display: 'inline-block' - }, - span: { - cursor: 'default' - }, - spanType: { - marginLeft: 5, - marginRight: 5 - } -}; - -@reactMixin.decorate(ExpandedStateHandlerMixin) -export default class JSONArrayNode extends React.Component { - defaultProps = { - data: [], - initialExpanded: false - }; - - // flag to see if we still need to render our child nodes - needsChildNodes = true; - - // cache store for our child nodes - renderedChildren = []; - - // cache store for the number of items string we display - itemString = false; - - constructor(props) { - super(props); - this.state = { - expanded: this.props.initialExpanded, - createdChildNodes: false - }; - } - - // Returns the child nodes for each element in the array. If we have - // generated them previously, we return from cache, otherwise we create - // them. - getChildNodes() { - if (this.state.expanded && this.needsChildNodes) { - let childNodes = []; - this.props.data.forEach((element, idx) => { - let prevData; - if (typeof this.props.previousData !== 'undefined' && this.props.previousData !== null) { - prevData = this.props.previousData[idx]; - } - const node = grabNode(idx, element, prevData, this.props.theme); - if (node !== false) { - childNodes.push(node); - } - }); - this.needsChildNodes = false; - this.renderedChildren = childNodes; - } - return this.renderedChildren; - } - - // Returns the "n Items" string for this node, generating and - // caching it if it hasn't been created yet. - getItemString() { - if (!this.itemString) { - this.itemString = this.props.data.length + ' item' + (this.props.data.length !== 1 ? 's' : ''); - } - return this.itemString; - } - - render() { - const childNodes = this.getChildNodes(); - const childListStyle = { - padding: 0, - margin: 0, - listStyle: 'none', - display: (this.state.expanded) ? 'block' : 'none' - }; - let containerStyle; - let spanStyle = { - ...styles.span, - color: this.props.theme.base0E - }; - containerStyle = { - ...styles.base - }; - if (this.state.expanded) { - spanStyle = { - ...spanStyle, - color: this.props.theme.base03 - }; - } - return ( -
  • - - - - [] - {this.getItemString()} - -
      - {childNodes} -
    -
  • - ); - } -} diff --git a/src/react/JSONTree/JSONArrow.js b/src/react/JSONTree/JSONArrow.js deleted file mode 100644 index 4e94a8a8b9..0000000000 --- a/src/react/JSONTree/JSONArrow.js +++ /dev/null @@ -1,42 +0,0 @@ -import React from 'react'; - -const styles = { - base: { - display: 'inline-block', - marginLeft: 0, - marginTop: 8, - marginRight: 5, - 'float': 'left', - transition: '150ms', - WebkitTransition: '150ms', - MozTransition: '150ms', - borderLeft: '5px solid transparent', - borderRight: '5px solid transparent', - borderTopWidth: 5, - borderTopStyle: 'solid', - WebkitTransform: 'rotateZ(-90deg)', - MozTransform: 'rotateZ(-90deg)', - transform: 'rotateZ(-90deg)' - }, - open: { - WebkitTransform: 'rotateZ(0deg)', - MozTransform: 'rotateZ(0deg)', - transform: 'rotateZ(0deg)' - } -}; - -export default class JSONArrow extends React.Component { - render() { - let style = { - ...styles.base, - borderTopColor: this.props.theme.base0D - }; - if (this.props.open) { - style = { - ...style, - ...styles.open - }; - } - return
    ; - } -} diff --git a/src/react/JSONTree/JSONBooleanNode.js b/src/react/JSONTree/JSONBooleanNode.js deleted file mode 100644 index 73b2ce9f07..0000000000 --- a/src/react/JSONTree/JSONBooleanNode.js +++ /dev/null @@ -1,40 +0,0 @@ -import React from 'react'; -import reactMixin from 'react-mixin'; -import { SquashClickEventMixin } from './mixins'; -import hexToRgb from '../../utils/hexToRgb'; - -const styles = { - base: { - paddingTop: 3, - paddingBottom: 3, - paddingRight: 0, - marginLeft: 14 - }, - label: { - display: 'inline-block', - marginRight: 5 - } -}; - -@reactMixin.decorate(SquashClickEventMixin) -export default class JSONBooleanNode extends React.Component { - render() { - const truthString = (this.props.value) ? 'true' : 'false'; - let backgroundColor = 'transparent'; - if (this.props.previousValue !== this.props.value) { - const bgColor = hexToRgb(this.props.theme.base06); - backgroundColor = `rgba(${bgColor.r}, ${bgColor.g}, ${bgColor.b}, 0.1)`; - } - return ( -
  • - - {truthString} -
  • - ); - } -} diff --git a/src/react/JSONTree/JSONIterableNode.js b/src/react/JSONTree/JSONIterableNode.js deleted file mode 100644 index 34038b37bb..0000000000 --- a/src/react/JSONTree/JSONIterableNode.js +++ /dev/null @@ -1,143 +0,0 @@ -import React from 'react'; -import reactMixin from 'react-mixin'; -import { ExpandedStateHandlerMixin } from './mixins'; -import JSONArrow from './JSONArrow'; -import grabNode from './grab-node'; - -const styles = { - base: { - position: 'relative', - paddingTop: 3, - paddingBottom: 3, - paddingRight: 0, - marginLeft: 14 - }, - label: { - margin: 0, - padding: 0, - display: 'inline-block' - }, - span: { - cursor: 'default' - }, - spanType: { - marginLeft: 5, - marginRight: 5 - } -}; - -@reactMixin.decorate(ExpandedStateHandlerMixin) -export default class JSONIterableNode extends React.Component { - defaultProps = { - data: [], - initialExpanded: false - }; - - // flag to see if we still need to render our child nodes - needsChildNodes = true; - - // cache store for our child nodes - renderedChildren = []; - - // cache store for the number of items string we display - itemString = false; - - constructor(props) { - super(props); - this.state = { - expanded: this.props.initialExpanded, - createdChildNodes: false - }; - } - - // Returns the child nodes for each entry in iterable. If we have - // generated them previously, we return from cache, otherwise we create - // them. - getChildNodes() { - if (this.state.expanded && this.needsChildNodes) { - let childNodes = []; - for (const entry of this.props.data) { - let key = null; - let value = null; - if (Array.isArray(entry)) { - [key, value] = entry; - } else { - key = childNodes.length; - value = entry; - } - - let prevData; - if (typeof this.props.previousData !== 'undefined' && this.props.previousData !== null) { - prevData = this.props.previousData[key]; - } - const node = grabNode(key, value, prevData, this.props.theme); - if (node !== false) { - childNodes.push(node); - } - } - this.needsChildNodes = false; - this.renderedChildren = childNodes; - } - return this.renderedChildren; - } - - // Returns the "n entries" string for this node, generating and - // caching it if it hasn't been created yet. - getItemString() { - if (!this.itemString) { - const { data } = this.props; - let count = 0; - if (Number.isSafeInteger(data.size)) { - count = data.size; - } else { - for (const entry of data) { // eslint-disable-line no-unused-vars - count += 1; - } - } - this.itemString = count + ' entr' + (count !== 1 ? 'ies' : 'y'); - } - return this.itemString; - } - - render() { - const childNodes = this.getChildNodes(); - const childListStyle = { - padding: 0, - margin: 0, - listStyle: 'none', - display: (this.state.expanded) ? 'block' : 'none' - }; - let containerStyle; - let spanStyle = { - ...styles.span, - color: this.props.theme.base0E - }; - containerStyle = { - ...styles.base - }; - if (this.state.expanded) { - spanStyle = { - ...spanStyle, - color: this.props.theme.base03 - }; - } - return ( -
  • - - - - () - {this.getItemString()} - -
      - {childNodes} -
    -
  • - ); - } -} diff --git a/src/react/JSONTree/JSONNullNode.js b/src/react/JSONTree/JSONNullNode.js deleted file mode 100644 index 6e11298a04..0000000000 --- a/src/react/JSONTree/JSONNullNode.js +++ /dev/null @@ -1,39 +0,0 @@ -import React from 'react'; -import reactMixin from 'react-mixin'; -import { SquashClickEventMixin } from './mixins'; -import hexToRgb from '../../utils/hexToRgb'; - -const styles = { - base: { - paddingTop: 3, - paddingBottom: 3, - paddingRight: 0, - marginLeft: 14 - }, - label: { - display: 'inline-block', - marginRight: 5 - } -}; - -@reactMixin.decorate(SquashClickEventMixin) -export default class JSONNullNode extends React.Component { - render() { - let backgroundColor = 'transparent'; - if (this.props.previousValue !== this.props.value) { - const bgColor = hexToRgb(this.props.theme.base06); - backgroundColor = `rgba(${bgColor.r}, ${bgColor.g}, ${bgColor.b}, 0.1)`; - } - return ( -
  • - - null -
  • - ); - } -} diff --git a/src/react/JSONTree/JSONNumberNode.js b/src/react/JSONTree/JSONNumberNode.js deleted file mode 100644 index d8b2b9d542..0000000000 --- a/src/react/JSONTree/JSONNumberNode.js +++ /dev/null @@ -1,39 +0,0 @@ -import React from 'react'; -import reactMixin from 'react-mixin'; -import { SquashClickEventMixin } from './mixins'; -import hexToRgb from '../../utils/hexToRgb'; - -const styles = { - base: { - paddingTop: 3, - paddingBottom: 3, - paddingRight: 0, - marginLeft: 14 - }, - label: { - display: 'inline-block', - marginRight: 5 - } -}; - -@reactMixin.decorate(SquashClickEventMixin) -export default class JSONNumberNode extends React.Component { - render() { - let backgroundColor = 'transparent'; - if (this.props.previousValue !== this.props.value) { - const bgColor = hexToRgb(this.props.theme.base06); - backgroundColor = `rgba(${bgColor.r}, ${bgColor.g}, ${bgColor.b}, 0.1)`; - } - return ( -
  • - - {this.props.value} -
  • - ); - } -} diff --git a/src/react/JSONTree/JSONObjectNode.js b/src/react/JSONTree/JSONObjectNode.js deleted file mode 100644 index 1b79659ce6..0000000000 --- a/src/react/JSONTree/JSONObjectNode.js +++ /dev/null @@ -1,126 +0,0 @@ -import React from 'react'; -import reactMixin from 'react-mixin'; -import { ExpandedStateHandlerMixin } from './mixins'; -import JSONArrow from './JSONArrow'; -import grabNode from './grab-node'; - -const styles = { - base: { - position: 'relative', - paddingTop: 3, - paddingBottom: 3, - marginLeft: 14 - }, - label: { - margin: 0, - padding: 0, - display: 'inline-block' - }, - span: { - cursor: 'default' - }, - spanType: { - marginLeft: 5, - marginRight: 5 - } -}; - -@reactMixin.decorate(ExpandedStateHandlerMixin) -export default class JSONObjectNode extends React.Component { - defaultProps = { - data: [], - initialExpanded: false - }; - // cache store for the number of items string we display - itemString = false; - - // flag to see if we still need to render our child nodes - needsChildNodes = true; - - // cache store for our child nodes - renderedChildren = []; - - constructor(props) { - super(props); - this.state = { - expanded: this.props.initialExpanded, - createdChildNodes: false - }; - } - - // Returns the child nodes for each element in the object. If we have - // generated them previously, we return from cache, otherwise we create - // them. - getChildNodes() { - if (this.state.expanded && this.needsChildNodes) { - const obj = this.props.data; - let childNodes = []; - for (let k in obj) { - if (obj.hasOwnProperty(k)) { - let prevData; - if (typeof this.props.previousData !== 'undefined' && this.props.previousData !== null) { - prevData = this.props.previousData[k]; - } - const node = grabNode(k, obj[k], prevData, this.props.theme); - if (node !== false) { - childNodes.push(node); - } - } - } - this.needsChildNodes = false; - this.renderedChildren = childNodes; - } - return this.renderedChildren; - } - - // Returns the "n Items" string for this node, generating and - // caching it if it hasn't been created yet. - getItemString() { - if (!this.itemString) { - const len = Object.keys(this.props.data).length; - this.itemString = len + ' key' + (len !== 1 ? 's' : ''); - } - return this.itemString; - } - - render() { - let childListStyle = { - padding: 0, - margin: 0, - listStyle: 'none', - display: (this.state.expanded) ? 'block' : 'none' - }; - let containerStyle; - let spanStyle = { - ...styles.span, - color: this.props.theme.base0B - }; - containerStyle = { - ...styles.base - }; - if (this.state.expanded) { - spanStyle = { - ...spanStyle, - color: this.props.theme.base03 - }; - } - return ( -
  • - - - - {} - {this.getItemString()} - -
      - {this.getChildNodes()} -
    -
  • - ); - } -} diff --git a/src/react/JSONTree/JSONStringNode.js b/src/react/JSONTree/JSONStringNode.js deleted file mode 100644 index d687be3760..0000000000 --- a/src/react/JSONTree/JSONStringNode.js +++ /dev/null @@ -1,39 +0,0 @@ -import React from 'react'; -import reactMixin from 'react-mixin'; -import { SquashClickEventMixin } from './mixins'; -import hexToRgb from '../../utils/hexToRgb'; - -const styles = { - base: { - paddingTop: 3, - paddingBottom: 3, - paddingRight: 0, - marginLeft: 14 - }, - label: { - display: 'inline-block', - marginRight: 5 - } -}; - -@reactMixin.decorate(SquashClickEventMixin) -export default class JSONStringNode extends React.Component { - render() { - let backgroundColor = 'transparent'; - if (this.props.previousValue !== this.props.value) { - const bgColor = hexToRgb(this.props.theme.base06); - backgroundColor = `rgba(${bgColor.r}, ${bgColor.g}, ${bgColor.b}, 0.1)`; - } - return ( -
  • - - "{this.props.value}" -
  • - ); - } -} diff --git a/src/react/JSONTree/grab-node.js b/src/react/JSONTree/grab-node.js deleted file mode 100644 index f94012a848..0000000000 --- a/src/react/JSONTree/grab-node.js +++ /dev/null @@ -1,29 +0,0 @@ -import React from 'react'; -import objType from './obj-type'; -import JSONObjectNode from './JSONObjectNode'; -import JSONArrayNode from './JSONArrayNode'; -import JSONIterableNode from './JSONIterableNode'; -import JSONStringNode from './JSONStringNode'; -import JSONNumberNode from './JSONNumberNode'; -import JSONBooleanNode from './JSONBooleanNode'; -import JSONNullNode from './JSONNullNode'; - -export default function(key, value, prevValue, theme) { - const nodeType = objType(value); - if (nodeType === 'Object') { - return ; - } else if (nodeType === 'Array') { - return ; - } else if (nodeType === 'Iterable') { - return ; - } else if (nodeType === 'String') { - return ; - } else if (nodeType === 'Number') { - return ; - } else if (nodeType === 'Boolean') { - return ; - } else if (nodeType === 'Null') { - return ; - } - return false; -} diff --git a/src/react/JSONTree/index.js b/src/react/JSONTree/index.js deleted file mode 100644 index bbac958068..0000000000 --- a/src/react/JSONTree/index.js +++ /dev/null @@ -1,56 +0,0 @@ -// ES6 + inline style port of JSONViewer https://bitbucket.org/davevedder/react-json-viewer/ -// all credits and original code to the author -// Dave Vedder http://www.eskimospy.com/ -// port by Daniele Zannotti http://www.github.com/dzannotti - -import React from 'react'; -import objectType from './obj-type'; -import JSONObjectNode from './JSONObjectNode'; -import JSONArrayNode from './JSONArrayNode'; - -const styles = { - tree: { - border: 0, - padding: 0, - marginTop: 8, - marginBottom: 8, - marginLeft: 2, - marginRight: 0, - fontSize: '0.90em', - listStyle: 'none', - MozUserSelect: 'none', - WebkitUserSelect: 'none' - } -}; - -export default class JSONTree extends React.Component { - static propTypes = { - data: React.PropTypes.oneOfType([ - React.PropTypes.array, - React.PropTypes.object - ]).isRequired - }; - - constructor(props) { - super(props); - } - - render() { - const nodeType = objectType(this.props.data); - let rootNode = false; - const keyName = this.props.keyName || 'root'; - if (nodeType === 'Object') { - rootNode = ; - } else if (nodeType === 'Array') { - rootNode = ; - } - return ( -
      - {rootNode} -
    - ); - } -} diff --git a/src/react/JSONTree/mixins/expanded-state-handler.js b/src/react/JSONTree/mixins/expanded-state-handler.js deleted file mode 100644 index 4cf30c2a9a..0000000000 --- a/src/react/JSONTree/mixins/expanded-state-handler.js +++ /dev/null @@ -1,21 +0,0 @@ -import deepEqual from '../../../utils/deepEqual'; - -export default { - handleClick(e) { - e.stopPropagation(); - this.setState({ - expanded: !this.state.expanded - }); - }, - - componentWillReceiveProps() { - // resets our caches and flags we need to build child nodes again - this.renderedChildren = []; - this.itemString = false; - this.needsChildNodes = true; - }, - - shouldComponentUpdate(nextProps, nextState) { - return !deepEqual(this.state, nextState) || !deepEqual(this.props, nextProps); - } -}; diff --git a/src/react/JSONTree/mixins/index.js b/src/react/JSONTree/mixins/index.js deleted file mode 100644 index 6ee2b386c5..0000000000 --- a/src/react/JSONTree/mixins/index.js +++ /dev/null @@ -1,2 +0,0 @@ -export { default as SquashClickEventMixin } from './squash-click-event'; -export { default as ExpandedStateHandlerMixin } from './expanded-state-handler'; diff --git a/src/react/JSONTree/mixins/squash-click-event.js b/src/react/JSONTree/mixins/squash-click-event.js deleted file mode 100644 index 233a9864a2..0000000000 --- a/src/react/JSONTree/mixins/squash-click-event.js +++ /dev/null @@ -1,5 +0,0 @@ -export default { - handleClick(e) { - e.stopPropagation(); - } -}; diff --git a/src/react/JSONTree/obj-type.js b/src/react/JSONTree/obj-type.js deleted file mode 100644 index fb12060633..0000000000 --- a/src/react/JSONTree/obj-type.js +++ /dev/null @@ -1,8 +0,0 @@ -export default function(obj) { - if (obj !== null && typeof obj === 'object' && !Array.isArray(obj) && - typeof obj[Symbol.iterator] === 'function' - ) { - return 'Iterable'; - } - return Object.prototype.toString.call(obj).slice(8, -1); -} diff --git a/src/react/LogMonitorEntry.js b/src/react/LogMonitorEntry.js index 0dcff40ee2..cce7ea5504 100644 --- a/src/react/LogMonitorEntry.js +++ b/src/react/LogMonitorEntry.js @@ -1,5 +1,5 @@ import React, { PropTypes } from 'react'; -import JSONTree from './JSONTree'; +import JSONTree from 'react-json-tree'; import LogMonitorEntryAction from './LogMonitorEntryAction'; const styles = { diff --git a/src/react/LogMonitorEntryAction.js b/src/react/LogMonitorEntryAction.js index b459da2a19..508d7c7216 100644 --- a/src/react/LogMonitorEntryAction.js +++ b/src/react/LogMonitorEntryAction.js @@ -1,5 +1,5 @@ import React from 'react'; -import JSONTree from './JSONTree'; +import JSONTree from 'react-json-tree'; const styles = { actionBar: { diff --git a/src/utils/deepEqual.js b/src/utils/deepEqual.js deleted file mode 100644 index 847c4472ce..0000000000 --- a/src/utils/deepEqual.js +++ /dev/null @@ -1,22 +0,0 @@ -function deepEqual(x, y) { - if ((typeof x === 'object' && x !== null) && (typeof y === 'object' && y !== null)) { - if (Object.keys(x).length !== Object.keys(y).length) { - return false; - } - for (let prop in x) { - if (y.hasOwnProperty(prop)) { - if (!deepEqual(x[prop], y[prop])) { - return false; - } - } else { - return false; - } - } - return true; - } else if (x !== y) { - return false; - } - return true; -} - -export default deepEqual; diff --git a/src/utils/hexToRgb.js b/src/utils/hexToRgb.js deleted file mode 100644 index af00785611..0000000000 --- a/src/utils/hexToRgb.js +++ /dev/null @@ -1,8 +0,0 @@ -export default function(hex) { - const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); - return result ? { - r: parseInt(result[1], 16), - g: parseInt(result[2], 16), - b: parseInt(result[3], 16) - } : null; -}