Add pane resizing
Refactor styles Update autoExpand with filtered result count Add redux batch reducer
This commit is contained in:
@@ -20,6 +20,23 @@ import { settingsActions, treeActions } from '../actions'
|
||||
import { TopicOrder } from '../reducers/Settings'
|
||||
import BrokerStatistics from './BrokerStatistics'
|
||||
|
||||
export const autoExpandLimitSet = [{
|
||||
limit: 0,
|
||||
name: 'Collapsed',
|
||||
}, {
|
||||
limit: 2,
|
||||
name: 'Few',
|
||||
}, {
|
||||
limit: 3,
|
||||
name: 'Some',
|
||||
}, {
|
||||
limit: 10,
|
||||
name: 'Most',
|
||||
}, {
|
||||
limit: 1E6,
|
||||
name: 'All',
|
||||
}]
|
||||
|
||||
const styles: StyleRulesCallback = theme => ({
|
||||
drawer: {
|
||||
backgroundColor: theme.palette.background.default,
|
||||
@@ -87,6 +104,8 @@ class Settings extends React.Component<Props, {}> {
|
||||
|
||||
private renderAutoExpand() {
|
||||
const { classes, autoExpandLimit } = this.props
|
||||
|
||||
const limits = autoExpandLimitSet.map(limit => <MenuItem key={limit.limit} value={limit.limit}>{limit.name}</MenuItem>)
|
||||
return (
|
||||
<div style={{ padding: '8px', display: 'flex' }}>
|
||||
<InputLabel htmlFor="auto-expand" style={{ flex: '1', marginTop: '8px' }}>Auto Expand</InputLabel>
|
||||
@@ -98,11 +117,7 @@ class Settings extends React.Component<Props, {}> {
|
||||
className={classes.input}
|
||||
style={{ flex: '1' }}
|
||||
>
|
||||
<MenuItem value={0}><em>Collapsed</em></MenuItem>
|
||||
<MenuItem value={2}>Few</MenuItem>
|
||||
<MenuItem value={3}>Some</MenuItem>
|
||||
<MenuItem value={10}>Most</MenuItem>
|
||||
<MenuItem value={1E6}>All</MenuItem>
|
||||
{limits}
|
||||
</Select>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -26,11 +26,11 @@ const styles = (theme: Theme) => {
|
||||
display: 'block',
|
||||
marginLeft: '10px',
|
||||
},
|
||||
hover: {
|
||||
'&:hover': {
|
||||
backgroundColor: 'rgba(80, 80, 80, 0.35)',
|
||||
},
|
||||
},
|
||||
// hover: {
|
||||
// '&:hover': {
|
||||
// backgroundColor: 'rgba(80, 80, 80, 0.35)',
|
||||
// },
|
||||
// },
|
||||
topicSelect: {
|
||||
float: 'right' as 'right',
|
||||
opacity: 0,
|
||||
@@ -51,7 +51,7 @@ interface Props {
|
||||
performanceCallback?: ((ms: number) => void) | undefined
|
||||
autoExpandLimit: number
|
||||
classes: any
|
||||
style?: React.CSSProperties
|
||||
className?: string
|
||||
}
|
||||
|
||||
interface State {
|
||||
@@ -68,6 +68,7 @@ class TreeNode extends React.Component<Props, State> {
|
||||
|
||||
private willUpdateTime: number = performance.now()
|
||||
private titleRef?: React.RefObject<HTMLDivElement> = React.createRef<HTMLDivElement>()
|
||||
private nodeRef?: React.RefObject<HTMLDivElement> = React.createRef<HTMLDivElement>()
|
||||
private topicSelectRef?: React.RefObject<HTMLDivElement> = React.createRef<HTMLDivElement>()
|
||||
|
||||
private subnodesDidchange = () => {
|
||||
@@ -119,6 +120,7 @@ class TreeNode extends React.Component<Props, State> {
|
||||
this.removeSubscriber(treeNode)
|
||||
this.topicSelectRef = undefined
|
||||
this.titleRef = undefined
|
||||
this.nodeRef = undefined
|
||||
}
|
||||
|
||||
private stateHasChanged(newState: State) {
|
||||
@@ -177,11 +179,11 @@ class TreeNode extends React.Component<Props, State> {
|
||||
return (
|
||||
<div
|
||||
key={this.props.treeNode.hash()}
|
||||
className={`${classes.node} ${!this.props.isRoot ? classes.hover : ''}`}
|
||||
className={`${classes.node} ${this.props.className}`}
|
||||
onClick={this.didClickNode}
|
||||
style={this.props.style}
|
||||
onMouseOver={this.mouseOver}
|
||||
onMouseOut={this.mouseOut}
|
||||
ref={this.nodeRef}
|
||||
>
|
||||
<span ref={this.titleRef} style={animation}>
|
||||
<TreeNodeTitle
|
||||
@@ -191,14 +193,6 @@ class TreeNode extends React.Component<Props, State> {
|
||||
lastUpdate={this.props.treeNode.lastUpdate}
|
||||
/>
|
||||
</span>
|
||||
<div
|
||||
className={this.props.classes.topicSelect}
|
||||
ref={this.topicSelectRef}
|
||||
onClick={this.didSelectNode}
|
||||
title="Select topic"
|
||||
>
|
||||
<LabelImportant style={{ fontSize: '14px' }} />
|
||||
</div>
|
||||
{this.renderNodes()}
|
||||
</div>
|
||||
)
|
||||
@@ -206,12 +200,18 @@ class TreeNode extends React.Component<Props, State> {
|
||||
|
||||
private mouseOver = (event: React.MouseEvent) => {
|
||||
event.stopPropagation()
|
||||
if (this.nodeRef && this.nodeRef.current) {
|
||||
this.nodeRef.current.style.backgroundColor = 'rgba(100, 100, 100, 0.55)'
|
||||
}
|
||||
if (this.topicSelectRef && this.topicSelectRef.current) {
|
||||
this.topicSelectRef.current.style.opacity = '1'
|
||||
}
|
||||
}
|
||||
private mouseOut = (event: React.MouseEvent) => {
|
||||
event.stopPropagation()
|
||||
if (this.nodeRef && this.nodeRef.current) {
|
||||
this.nodeRef.current.style.backgroundColor = 'inherit'
|
||||
}
|
||||
if (this.topicSelectRef && this.topicSelectRef.current) {
|
||||
this.topicSelectRef.current.style.opacity = '0'
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import { AppState } from '../../reducers'
|
||||
import TreeNode from './TreeNode'
|
||||
import { connect } from 'react-redux'
|
||||
import { TopicOrder } from '../../reducers/Settings'
|
||||
import { Theme, withStyles } from '@material-ui/core'
|
||||
|
||||
export interface Props {
|
||||
lastUpdate: number
|
||||
@@ -16,6 +17,7 @@ export interface Props {
|
||||
filter?: string
|
||||
collapsed?: boolean | undefined
|
||||
didSelectNode?: (node: q.TreeNode) => void
|
||||
classes: any
|
||||
}
|
||||
|
||||
interface State {
|
||||
@@ -69,24 +71,19 @@ class TreeNodeSubnodes extends React.Component<Props, State> {
|
||||
this.renderMore()
|
||||
}
|
||||
|
||||
const listItemStyle = {
|
||||
padding: '3px 0px 0px 8px',
|
||||
}
|
||||
|
||||
const nodes = this.sortedNodes().slice(0, this.state.alreadyAdded)
|
||||
const listItems = nodes.map(node => (
|
||||
<div key={`${node.hash()}-${this.props.filter}`}>
|
||||
<TreeNode
|
||||
animateChages={this.props.animateChanges}
|
||||
treeNode={node}
|
||||
lastUpdate={node.lastUpdate}
|
||||
style={listItemStyle}
|
||||
/>
|
||||
</div>
|
||||
<TreeNode
|
||||
key={`${node.hash()}-${this.props.filter}`}
|
||||
animateChages={this.props.animateChanges}
|
||||
treeNode={node}
|
||||
lastUpdate={node.lastUpdate}
|
||||
className={this.props.classes.listItem}
|
||||
/>
|
||||
))
|
||||
|
||||
return (
|
||||
<span style={{ display: 'block', clear: 'both' }} >
|
||||
<span className={this.props.classes.list}>
|
||||
{listItems}
|
||||
</span>
|
||||
)
|
||||
@@ -100,4 +97,14 @@ const mapStateToProps = (state: AppState) => {
|
||||
}
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps)(TreeNodeSubnodes)
|
||||
const styles = (theme: Theme) => ({
|
||||
list: {
|
||||
display: 'block' as 'block',
|
||||
clear: 'both' as 'both',
|
||||
},
|
||||
listItem: {
|
||||
padding: '3px 0px 0px 8px',
|
||||
},
|
||||
})
|
||||
|
||||
export default withStyles(styles)(connect(mapStateToProps)(TreeNodeSubnodes))
|
||||
|
||||
@@ -3,6 +3,7 @@ import { connect } from 'react-redux'
|
||||
import { bindActionCreators } from 'redux'
|
||||
import { treeActions } from '../../actions'
|
||||
import * as q from '../../../../backend/src/Model'
|
||||
import { withStyles, Theme } from '@material-ui/core'
|
||||
|
||||
export interface TreeNodeProps extends React.HTMLAttributes<HTMLElement> {
|
||||
treeNode: q.TreeNode
|
||||
@@ -10,62 +11,33 @@ export interface TreeNodeProps extends React.HTMLAttributes<HTMLElement> {
|
||||
name?: string | undefined
|
||||
collapsed?: boolean | undefined
|
||||
lastUpdate: number
|
||||
classes: any
|
||||
}
|
||||
|
||||
class TreeNodeTitle extends React.Component<TreeNodeProps, {}> {
|
||||
private getStyles() {
|
||||
return {
|
||||
collapsedSubnodes: {
|
||||
color: 'white', // theme.palette.text.secondary,
|
||||
},
|
||||
container: {
|
||||
display: 'block',
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
private didSelectNode = (event: React.MouseEvent) => {
|
||||
event.stopPropagation()
|
||||
private mouseOver = (event: React.MouseEvent) => {
|
||||
if (this.props.treeNode.message) {
|
||||
this.props.actions.selectTopic(this.props.treeNode)
|
||||
}
|
||||
}
|
||||
|
||||
public render() {
|
||||
const style: React.CSSProperties = {
|
||||
lineHeight: '1em',
|
||||
whiteSpace: 'nowrap',
|
||||
}
|
||||
return (
|
||||
<span style={style} onMouseOver={this.didSelectNode}>
|
||||
<span className={this.props.classes.title} onMouseOver={this.mouseOver}>
|
||||
{this.renderExpander()} {this.renderSourceEdge()} {this.renderCollapsedSubnodes()} {this.renderValue()}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
private renderSourceEdge() {
|
||||
const style: React.CSSProperties = {
|
||||
fontWeight: 'bold',
|
||||
overflow: 'hidden',
|
||||
display: 'inline-block',
|
||||
}
|
||||
const name = this.props.name || (this.props.treeNode.sourceEdge && this.props.treeNode.sourceEdge.name)
|
||||
|
||||
return <span style={style}>{name}</span>
|
||||
return <span className={this.props.classes.sourceEdge}>{name}</span>
|
||||
}
|
||||
|
||||
private renderValue() {
|
||||
const style: React.CSSProperties = {
|
||||
whiteSpace: 'nowrap',
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
padding: '0',
|
||||
marginLeft: '5px',
|
||||
display: 'inline-block',
|
||||
}
|
||||
|
||||
return this.props.treeNode.message && this.props.treeNode.message.length > 0
|
||||
? <span style={style}> = {this.props.treeNode.message.value.toString()}</span>
|
||||
? <span className={this.props.classes.value}> = {this.props.treeNode.message.value.toString().slice(0, 120)}</span>
|
||||
: null
|
||||
}
|
||||
|
||||
@@ -83,7 +55,7 @@ class TreeNodeTitle extends React.Component<TreeNodeProps, {}> {
|
||||
}
|
||||
|
||||
const messages = this.props.treeNode.leafMessageCount()
|
||||
return <span style={this.getStyles().collapsedSubnodes}>({this.props.treeNode.childTopicCount()} topics, {messages} messages)</span>
|
||||
return <span className={this.props.classes.collapsedSubnodes}>({this.props.treeNode.childTopicCount()} topics, {messages} messages)</span>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,4 +65,27 @@ const mapDispatchToProps = (dispatch: any) => {
|
||||
}
|
||||
}
|
||||
|
||||
export default connect(null, mapDispatchToProps)(TreeNodeTitle)
|
||||
const styles = (theme: Theme) => ({
|
||||
value: {
|
||||
whiteSpace: 'nowrap' as 'nowrap',
|
||||
overflow: 'hidden' as 'hidden',
|
||||
textOverflow: 'ellipsis' as 'ellipsis',
|
||||
padding: '0',
|
||||
marginLeft: '5px',
|
||||
display: 'inline-block' as 'inline-block',
|
||||
},
|
||||
sourceEdge: {
|
||||
fontWeight: 'bold' as 'bold',
|
||||
overflow: 'hidden' as 'hidden',
|
||||
display: 'inline-block' as 'inline-block',
|
||||
},
|
||||
title: {
|
||||
lineHeight: '1em',
|
||||
whiteSpace: 'nowrap' as 'nowrap',
|
||||
},
|
||||
collapsedSubnodes: {
|
||||
color: theme.palette.text.secondary,
|
||||
},
|
||||
})
|
||||
|
||||
export default withStyles(styles)(connect(null, mapDispatchToProps)(TreeNodeTitle))
|
||||
|
||||
Reference in New Issue
Block a user