mirror of
https://github.com/reduxjs/redux-devtools.git
synced 2024-11-22 09:36:43 +03:00
Extract JSONTree
This commit is contained in:
parent
15c35b6417
commit
445e3c9ecd
|
@ -47,6 +47,7 @@
|
||||||
"redux": "^1.0.0 || 1.0.0-rc"
|
"redux": "^1.0.0 || 1.0.0-rc"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"react-json-tree": "^0.1.3",
|
||||||
"react-mixin": "^1.7.0",
|
"react-mixin": "^1.7.0",
|
||||||
"react-redux": "^0.9.0",
|
"react-redux": "^0.9.0",
|
||||||
"redux": "^1.0.1"
|
"redux": "^1.0.1"
|
||||||
|
|
|
@ -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 (
|
|
||||||
<li style={containerStyle}>
|
|
||||||
<JSONArrow theme={this.props.theme} open={this.state.expanded} onClick={::this.handleClick}/>
|
|
||||||
<label style={{
|
|
||||||
...styles.label,
|
|
||||||
color: this.props.theme.base0D
|
|
||||||
}} onClick={::this.handleClick}>
|
|
||||||
{this.props.keyName}:
|
|
||||||
</label>
|
|
||||||
<span style={spanStyle} onClick={::this.handleClick}>
|
|
||||||
<span style={styles.spanType}>[]</span>
|
|
||||||
{this.getItemString()}
|
|
||||||
</span>
|
|
||||||
<ol style={childListStyle}>
|
|
||||||
{childNodes}
|
|
||||||
</ol>
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 <div style={style} onClick={this.props.onClick}/>;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 (
|
|
||||||
<li style={{ ...styles.base, backgroundColor }} onClick={::this.handleClick}>
|
|
||||||
<label style={{
|
|
||||||
...styles.label,
|
|
||||||
color: this.props.theme.base0D
|
|
||||||
}}>
|
|
||||||
{this.props.keyName}:
|
|
||||||
</label>
|
|
||||||
<span style={{ color: this.props.theme.base09 }}>{truthString}</span>
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 (
|
|
||||||
<li style={containerStyle}>
|
|
||||||
<JSONArrow theme={this.props.theme} open={this.state.expanded} onClick={::this.handleClick}/>
|
|
||||||
<label style={{
|
|
||||||
...styles.label,
|
|
||||||
color: this.props.theme.base0D
|
|
||||||
}} onClick={::this.handleClick}>
|
|
||||||
{this.props.keyName}:
|
|
||||||
</label>
|
|
||||||
<span style={spanStyle} onClick={::this.handleClick}>
|
|
||||||
<span style={styles.spanType}>()</span>
|
|
||||||
{this.getItemString()}
|
|
||||||
</span>
|
|
||||||
<ol style={childListStyle}>
|
|
||||||
{childNodes}
|
|
||||||
</ol>
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 (
|
|
||||||
<li style={{ ...styles.base, backgroundColor }} onClick={::this.handleClick}>
|
|
||||||
<label style={{
|
|
||||||
...styles.label,
|
|
||||||
color: this.props.theme.base0D
|
|
||||||
}}>
|
|
||||||
{this.props.keyName}:
|
|
||||||
</label>
|
|
||||||
<span style={{ color: this.props.theme.base08 }}>null</span>
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 (
|
|
||||||
<li style={{ ...styles.base, backgroundColor }} onClick={::this.handleClick}>
|
|
||||||
<label style={{
|
|
||||||
...styles.label,
|
|
||||||
color: this.props.theme.base0D
|
|
||||||
}}>
|
|
||||||
{this.props.keyName}:
|
|
||||||
</label>
|
|
||||||
<span style={{ color: this.props.theme.base09 }}>{this.props.value}</span>
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 (
|
|
||||||
<li style={containerStyle}>
|
|
||||||
<JSONArrow theme={this.props.theme} open={this.state.expanded} onClick={::this.handleClick}/>
|
|
||||||
<label style={{
|
|
||||||
...styles.label,
|
|
||||||
color: this.props.theme.base0D
|
|
||||||
}} onClick={::this.handleClick}>
|
|
||||||
{this.props.keyName}:
|
|
||||||
</label>
|
|
||||||
<span style={spanStyle} onClick={::this.handleClick}>
|
|
||||||
<span style={styles.spanType}>{}</span>
|
|
||||||
{this.getItemString()}
|
|
||||||
</span>
|
|
||||||
<ul style={childListStyle}>
|
|
||||||
{this.getChildNodes()}
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 (
|
|
||||||
<li style={{ ...styles.base, backgroundColor }} onClick={::this.handleClick}>
|
|
||||||
<label style={{
|
|
||||||
...styles.label,
|
|
||||||
color: this.props.theme.base0D
|
|
||||||
}}>
|
|
||||||
{this.props.keyName}:
|
|
||||||
</label>
|
|
||||||
<span style={{ color: this.props.theme.base0B }}>"{this.props.value}"</span>
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 <JSONObjectNode data={value} previousData={prevValue} theme={theme} keyName={key} key={key} />;
|
|
||||||
} else if (nodeType === 'Array') {
|
|
||||||
return <JSONArrayNode data={value} previousData={prevValue} theme={theme} keyName={key} key={key} />;
|
|
||||||
} else if (nodeType === 'Iterable') {
|
|
||||||
return <JSONIterableNode data={value} previousData={prevValue} theme={theme} keyName={key} key={key} />;
|
|
||||||
} else if (nodeType === 'String') {
|
|
||||||
return <JSONStringNode keyName={key} previousValue={prevValue} theme={theme} value={value} key={key} />;
|
|
||||||
} else if (nodeType === 'Number') {
|
|
||||||
return <JSONNumberNode keyName={key} previousValue={prevValue} theme={theme} value={value} key={key} />;
|
|
||||||
} else if (nodeType === 'Boolean') {
|
|
||||||
return <JSONBooleanNode keyName={key} previousValue={prevValue} theme={theme} value={value} key={key} />;
|
|
||||||
} else if (nodeType === 'Null') {
|
|
||||||
return <JSONNullNode keyName={key} previousValue={prevValue} theme={theme} value={value} key={key} />;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
|
@ -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 <veddermatic@gmail.com> http://www.eskimospy.com/
|
|
||||||
// port by Daniele Zannotti http://www.github.com/dzannotti <dzannotti@me.com>
|
|
||||||
|
|
||||||
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 = <JSONObjectNode theme={this.props.theme} data={this.props.data} previousData={this.props.previousData} keyName={keyName} initialExpanded={true} />;
|
|
||||||
} else if (nodeType === 'Array') {
|
|
||||||
rootNode = <JSONArrayNode theme={this.props.theme} data={this.props.data} previousData={this.props.previousData} initialExpanded={true} keyName={keyName} />;
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<ul style={{
|
|
||||||
...styles.tree,
|
|
||||||
...this.props.style
|
|
||||||
}}>
|
|
||||||
{rootNode}
|
|
||||||
</ul>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,2 +0,0 @@
|
||||||
export { default as SquashClickEventMixin } from './squash-click-event';
|
|
||||||
export { default as ExpandedStateHandlerMixin } from './expanded-state-handler';
|
|
|
@ -1,5 +0,0 @@
|
||||||
export default {
|
|
||||||
handleClick(e) {
|
|
||||||
e.stopPropagation();
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -1,5 +1,5 @@
|
||||||
import React, { PropTypes } from 'react';
|
import React, { PropTypes } from 'react';
|
||||||
import JSONTree from './JSONTree';
|
import JSONTree from 'react-json-tree';
|
||||||
import LogMonitorEntryAction from './LogMonitorEntryAction';
|
import LogMonitorEntryAction from './LogMonitorEntryAction';
|
||||||
|
|
||||||
const styles = {
|
const styles = {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import JSONTree from './JSONTree';
|
import JSONTree from 'react-json-tree';
|
||||||
|
|
||||||
const styles = {
|
const styles = {
|
||||||
actionBar: {
|
actionBar: {
|
||||||
|
|
|
@ -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;
|
|
|
@ -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;
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user