From eb375073f92914b40d8f9a107ad21a36a6a24da1 Mon Sep 17 00:00:00 2001 From: Thomas Nordquist Date: Thu, 10 Jan 2019 10:34:09 +0100 Subject: [PATCH] Fix Sidebar & Mouse event target area Fix clipboard Fix invalid state in sidebar due to missing event termination --- app/src/App.tsx | 2 +- app/src/actions/index.ts | 3 +- app/src/components/Sidebar/NodeStats.tsx | 13 ++-- app/src/components/Sidebar/Sidebar.tsx | 72 ++++++++++++-------- app/src/components/Sidebar/Topic.tsx | 6 +- app/src/components/Tree/Tree.tsx | 3 +- app/src/components/Tree/TreeNode.tsx | 17 ++++- app/src/components/Tree/TreeNodeSubnodes.tsx | 3 +- app/src/components/Tree/TreeNodeTitle.tsx | 20 ++++-- app/src/index.tsx | 1 + app/src/reducers/index.ts | 31 ++++++--- 11 files changed, 111 insertions(+), 60 deletions(-) diff --git a/app/src/App.tsx b/app/src/App.tsx index f0369b6..1941fe9 100644 --- a/app/src/App.tsx +++ b/app/src/App.tsx @@ -91,7 +91,7 @@ class App extends React.Component { }} />
- +
diff --git a/app/src/actions/index.ts b/app/src/actions/index.ts index d6d9e2b..a3c5db6 100644 --- a/app/src/actions/index.ts +++ b/app/src/actions/index.ts @@ -1,3 +1,4 @@ import * as settingsActions from './Settings' +import * as treeActions from './Tree' -export { settingsActions } +export { settingsActions, treeActions } diff --git a/app/src/components/Sidebar/NodeStats.tsx b/app/src/components/Sidebar/NodeStats.tsx index ed6d726..91ccc1b 100644 --- a/app/src/components/Sidebar/NodeStats.tsx +++ b/app/src/components/Sidebar/NodeStats.tsx @@ -1,6 +1,5 @@ import * as React from 'react' import * as q from '../../../../backend/src/Model' -// import Drawer from '@material-ui/core/Drawer' import { Typography } from '@material-ui/core' interface Props { @@ -15,11 +14,13 @@ class NodeStats extends React.Component { public render() { const { node } = this.props - return
- Messages: #{node.messages} - Subtopics: {node.leafCount()} - Messages Subtopics: #{node.leafMessageCount()} -
+ return ( +
+ Messages: #{node.messages} + Subtopics: {node.leafCount()} + Messages Subtopics: #{node.leafMessageCount()} +
+ ) } } diff --git a/app/src/components/Sidebar/Sidebar.tsx b/app/src/components/Sidebar/Sidebar.tsx index b04d755..9ecfcfc 100644 --- a/app/src/components/Sidebar/Sidebar.tsx +++ b/app/src/components/Sidebar/Sidebar.tsx @@ -1,4 +1,6 @@ import * as React from 'react' +import { connect } from 'react-redux' +import { AppState } from '../../reducers' import * as q from '../../../../backend/src/Model' import { ExpansionPanel, ExpansionPanelDetails, ExpansionPanelSummary, Typography } from '@material-ui/core' import { withStyles, Theme, StyleRulesCallback } from '@material-ui/core/styles' @@ -63,9 +65,11 @@ class Sidebar extends React.Component { } public render() { - return
- {this.renderNode()} -
+ return ( +
+ {this.renderNode()} +
+ ) } private renderNode() { @@ -74,33 +78,41 @@ class Sidebar extends React.Component { const copyTopic = node ? : null const copyValue = node && node.message ? : null - return
- - }> - Topic {copyTopic} - - - - - - - }> - Value {copyValue} - - - - - - - }> - Stats - - - - - -
+ return ( +
+ + }> + Topic {copyTopic} + + + + + + + }> + Value {copyValue} + + + + + + + }> + Stats + + + {this.props.node ? : null} + + +
+ ) } } -export default withStyles(Sidebar.styles, { withTheme: true })(Sidebar) +const mapStateToProps = (state: AppState) => { + return { + node: state.selectedTopic, + } +} + +export default withStyles(Sidebar.styles, { withTheme: true })(connect(mapStateToProps)(Sidebar)) diff --git a/app/src/components/Sidebar/Topic.tsx b/app/src/components/Sidebar/Topic.tsx index c40afec..75831a6 100644 --- a/app/src/components/Sidebar/Topic.tsx +++ b/app/src/components/Sidebar/Topic.tsx @@ -31,7 +31,8 @@ class Topic extends React.Component { .map(node => node.sourceEdge) .filter(edge => Boolean(edge)) .map(edge => - [], + + )], ) if (breadCrumps.length === 0) { diff --git a/app/src/components/Tree/Tree.tsx b/app/src/components/Tree/Tree.tsx index dd36f2c..c9e2427 100644 --- a/app/src/components/Tree/Tree.tsx +++ b/app/src/components/Tree/Tree.tsx @@ -118,8 +118,7 @@ class Tree extends React.Component { name="/" collapsed={false} key="rootNode" - lastUpdate={0} - performanceCallback={this.performanceCallback} + lastUpdate={this.state.tree.lastUpdate} /> ) diff --git a/app/src/components/Tree/TreeNode.tsx b/app/src/components/Tree/TreeNode.tsx index a4474c1..4e7fc36 100644 --- a/app/src/components/Tree/TreeNode.tsx +++ b/app/src/components/Tree/TreeNode.tsx @@ -1,4 +1,7 @@ import * as React from 'react' +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/styles' @@ -29,6 +32,7 @@ const styles = (theme: Theme) => { } interface Props { + actions: any lastUpdate: number animateChages: boolean isRoot?: boolean @@ -39,6 +43,7 @@ interface Props { didSelectNode?: (node: q.TreeNode) => void classes: any autoExpandLimit: number + style?: React.CSSProperties } interface State { @@ -168,13 +173,13 @@ class TreeNode extends React.Component { key={this.props.treeNode.hash()} className={`${classes.node} ${!this.props.isRoot ? classes.hover : ''}`} onClick={this.didClickNode} + style={this.props.style} > {this.renderNodes()} @@ -185,7 +190,7 @@ class TreeNode extends React.Component { private didClickNode = (event: React.MouseEvent) => { event.stopPropagation() this.toggle() - this.props.didSelectNode && this.props.didSelectNode(this.props.treeNode) + this.props.actions.selectTopic(this.props.treeNode) } private renderNodes() { @@ -202,4 +207,10 @@ class TreeNode extends React.Component { } } -export default withStyles(styles)(TreeNode) +const mapDispatchToProps = (dispatch: any) => { + return { + actions: bindActionCreators(treeActions, dispatch), + } +} + +export default withStyles(styles)(connect(null, mapDispatchToProps)(TreeNode)) diff --git a/app/src/components/Tree/TreeNodeSubnodes.tsx b/app/src/components/Tree/TreeNodeSubnodes.tsx index 6c9a1e0..7d83439 100644 --- a/app/src/components/Tree/TreeNodeSubnodes.tsx +++ b/app/src/components/Tree/TreeNodeSubnodes.tsx @@ -49,13 +49,14 @@ class TreeNodeSubnodes extends React.Component { const nodes = this.sortedNodes() const listItems = nodes.map(node => ( -
+
)) diff --git a/app/src/components/Tree/TreeNodeTitle.tsx b/app/src/components/Tree/TreeNodeTitle.tsx index bf00439..09de0bd 100644 --- a/app/src/components/Tree/TreeNodeTitle.tsx +++ b/app/src/components/Tree/TreeNodeTitle.tsx @@ -1,12 +1,15 @@ import * as React from 'react' +import { connect } from 'react-redux' +import { bindActionCreators } from 'redux' +import { treeActions } from '../../actions' import * as q from '../../../../backend/src/Model' import { withTheme, Theme } from '@material-ui/core/styles' export interface TreeNodeProps extends React.HTMLAttributes { treeNode: q.TreeNode + actions: any name?: string | undefined collapsed?: boolean | undefined - didSelectNode?: (node: q.TreeNode) => void theme: Theme } @@ -23,9 +26,10 @@ class TreeNodeTitle extends React.Component { } } - private didSelectNode = () => { + private didSelectNode = (event: React.MouseEvent) => { + event.stopPropagation() if (this.props.treeNode.message) { - this.props.didSelectNode && this.props.didSelectNode(this.props.treeNode) + this.props.actions.selectTopic(this.props.treeNode) } } @@ -59,7 +63,7 @@ class TreeNodeTitle extends React.Component { overflow: 'hidden', textOverflow: 'ellipsis', padding: '0', - paddingLeft: '5px', + marginLeft: '5px', display: 'inline-block', } return this.props.treeNode.message @@ -85,4 +89,10 @@ class TreeNodeTitle extends React.Component { } } -export default withTheme()(TreeNodeTitle) +const mapDispatchToProps = (dispatch: any) => { + return { + actions: bindActionCreators(treeActions, dispatch), + } +} + +export default withTheme()(connect(null, mapDispatchToProps)(TreeNodeTitle)) diff --git a/app/src/index.tsx b/app/src/index.tsx index c573ae5..e864c1a 100644 --- a/app/src/index.tsx +++ b/app/src/index.tsx @@ -15,6 +15,7 @@ const initialAppState = { nodeOrder: NodeOrder.none, visible: false, }, + selectedNode: undefined, } const store = createStore(reducers, initialAppState) diff --git a/app/src/reducers/index.ts b/app/src/reducers/index.ts index 89a2a41..0419b80 100644 --- a/app/src/reducers/index.ts +++ b/app/src/reducers/index.ts @@ -1,19 +1,29 @@ import { Reducer, Action } from 'redux' +import * as q from '../../../backend/src/Model' export enum ActionTypes { setAutoExpandLimit = 'SET_AUTO_EXPAND_LIMIT', toggleSettingsVisibility = 'TOGGLE_SETTINGS_VISIBILITY', setNodeOrder = 'SET_NODE_ORDER', + selectTopic = 'SELECT_TOPIC', } -interface SettingsAction extends Action { +interface CustomAction extends Action { type: ActionTypes, autoExpandLimit?: number nodeOrder?: NodeOrder + selectedTopic?: q.TreeNode } export interface AppState { - settings: SettingsModel + settings: SettingsState, + selectedTopic?: q.TreeNode +} + +export interface SettingsState { + autoExpandLimit: number + visible: boolean + nodeOrder: NodeOrder } export enum NodeOrder { @@ -23,13 +33,7 @@ export enum NodeOrder { topics = '#topics', } -export interface SettingsModel { - autoExpandLimit: number - visible: boolean - nodeOrder: NodeOrder -} - -const reducer: Reducer = (state, action) => { +const reducer: Reducer = (state, action) => { if (!state) { throw Error('No initial state') } @@ -57,6 +61,15 @@ const reducer: Reducer = (state, action) = nodeOrder: state.settings.nodeOrder, }, } + case ActionTypes.selectTopic: + if (!action.selectedTopic) { + return state + } + return { + ...state, + settings: state.settings, + selectedTopic: action.selectedTopic, + } case ActionTypes.setNodeOrder: if (!action.nodeOrder) { return state