import * as q from '../../../../backend/src/Model' import * as React from 'react' import Clear from '@material-ui/icons/Clear' import Copy from '../Copy' import DateFormatter from '../helper/DateFormatter' import Delete from '@material-ui/icons/Delete' import DeleteForever from '@material-ui/icons/DeleteForever' import ExpandMore from '@material-ui/icons/ExpandMore' import MessageHistory from './MessageHistory' import NodeStats from './NodeStats' import Topic from './Topic' import { AppState } from '../../reducers' import { bindActionCreators } from 'redux' import { connect } from 'react-redux' import { default as ReactResizeDetector } from 'react-resize-detector' import { sidebarActons } from '../../actions' import { StyleRulesCallback, Theme, withStyles } from '@material-ui/core/styles' import { TopicViewModel } from '../../TopicViewModel' import { Button, ExpansionPanel, ExpansionPanelDetails, ExpansionPanelSummary, Fade, Paper, Popper, Typography, Tooltip, Badge, } from '@material-ui/core' import CustomIconButton from '../CustomIconButton'; import { max } from 'moment'; const throttle = require('lodash.throttle') const Publish = React.lazy(() => import('./Publish/Publish')) const ValueRenderer = React.lazy(() => import('./ValueRenderer')) interface Props { node?: q.TreeNode, actions: typeof sidebarActons, classes: any, connectionId?: string, } interface State { node: q.TreeNode compareMessage?: q.Message valueRenderWidth: number } class Sidebar extends React.Component { private valueRef: any = React.createRef() private updateNode = throttle(() => { this.setState(this.state) }, 300) constructor(props: any) { super(props) console.error('Find and fix me #state') this.state = { node: new q.Tree(), valueRenderWidth: 300 } } public componentWillReceiveProps(nextProps: Props) { this.props.node && this.removeUpdateListener(this.props.node) nextProps.node && this.registerUpdateListener(nextProps.node) this.props.node && this.setState({ node: this.props.node }) if (this.props.node !== nextProps.node) { this.setState({ compareMessage: undefined }) } } public componentWillUnmount() { this.props.node && this.removeUpdateListener(this.props.node) } private registerUpdateListener(node: q.TreeNode) { node.onMerge.subscribe(this.updateNode) node.onMessage.subscribe(this.updateNode) } private removeUpdateListener(node: q.TreeNode) { node.onMerge.unsubscribe(this.updateNode) node.onMessage.unsubscribe(this.updateNode) } public render() { return (
{this.renderNode()}
) } private detailsStyle = { padding: '0px 16px 8px 8px', display: 'block' } private renderTopicDeleteButton() { if (!this.props.node) { return null } return this.deleteTopic(this.props.node)}> } private renderRecursiveTopicDeleteButton() { const deleteLimit = 50 const topicCount = this.props.node ? this.props.node.childTopicCount() : 0 if (!this.props.node || topicCount <= 1) { return null } return ( this.deleteTopic(this.props.node, true, deleteLimit)}> {topicCount >= deleteLimit ? '50+' : topicCount}} color="secondary" > ) } private deleteTopic = (topic?: q.TreeNode, recursive: boolean = false, maxCount = 50) => { if (!topic) { return } this.props.actions.clearTopic(topic, recursive, maxCount) } private renderNode() { const { classes, node } = this.props const copyTopic = node ? : null const deleteTopic = this.renderTopicDeleteButton() const deleteRecursiveTopic = this.renderRecursiveTopicDeleteButton() const copyValue = node && node.message ? : null const summeryStyle = { minHeight: '0' } return (
} style={summeryStyle}> Topic {copyTopic} {deleteTopic} {deleteRecursiveTopic} } style={summeryStyle}> Value {copyValue} {this.messageMetaInfo()}
Loading...
}>
{this.showValueComparison} } style={summeryStyle}> Publish Loading...}> } style={summeryStyle}> Stats {this.renderNodeStats()} ) } private valueRenderWidthChange = (width: number) => { this.setState({ valueRenderWidth: width }) } private showValueComparison = (a: any) => ( ) private messageMetaInfo() { if (!this.props.node || !this.props.node.message || !this.props.node.mqttMessage) { return null } const retainedButton = ( ) return (
QoS: {this.props.node.mqttMessage.qos}
{this.props.node.mqttMessage.retain ? retainedButton : null}
) } private handleMessageHistorySelect = (message: q.Message) => { if (message !== this.state.compareMessage) { this.setState({ compareMessage: message }) } else { this.setState({ compareMessage: undefined }) } } private renderNodeStats() { if (!this.props.node) { return null } return ( ) } } const mapStateToProps = (state: AppState) => { return { node: state.tree.selectedTopic, } } const mapDispatchToProps = (dispatch: any) => { return { actions: bindActionCreators(sidebarActons, dispatch), } } const styles: StyleRulesCallback = (theme: Theme) => { return { drawer: { display: 'block', height: '100%', }, valuePaper: { margin: theme.spacing(1), }, heading: { fontSize: theme.typography.pxToRem(15), fontWeight: theme.typography.fontWeightRegular, }, } } export default withStyles(styles)(connect(mapStateToProps, mapDispatchToProps)(Sidebar))