import * as q from '../../../../../backend/src/Model' import * as React from 'react' import ClearAdornment from '../../helper/ClearAdornment' import FormatAlignLeft from '@material-ui/icons/FormatAlignLeft' import History from '../HistoryDrawer' import Message from './Model/Message' import Navigation from '@material-ui/icons/Navigation' import { AppState } from '../../../reducers' import { bindActionCreators } from 'redux' import { connect } from 'react-redux' import { default as AceEditor } from 'react-ace' import { globalActions, publishActions } from '../../../actions' import { TopicViewModel } from '../../../model/TopicViewModel' import 'brace/mode/json' import 'brace/theme/dawn' import 'brace/theme/monokai' import 'brace/mode/xml' import 'brace/mode/text' import 'react-ace' import { Button, FormControlLabel, Radio, RadioGroup, TextField, FormControl, InputLabel, Input, Checkbox, MenuItem, Tooltip, Fab, Theme, withTheme, } from '@material-ui/core' const sha1 = require('sha1') interface Props { connectionId?: string topic?: string payload?: string actions: typeof publishActions globalActions: typeof globalActions retain: boolean editorMode: string qos: 0 | 1 | 2 theme: Theme } interface State { history: Array } class Publish extends React.Component { private editorOptions = { showLineNumbers: false, tabSize: 2, } constructor(props: any) { super(props) this.state = { history: [] } } private updatePayload = (payload: string, event?: any) => { this.props.actions.setPayload(payload) } private updateTopic = (e: React.ChangeEvent) => { this.props.actions.setTopic(e.target.value) } private updateMode = (e: React.ChangeEvent<{}>, value: string) => { this.props.actions.setEditorMode(value) } private publish = (e: React.MouseEvent) => { e.stopPropagation() if (!this.props.connectionId) { return } this.props.actions.publish(this.props.connectionId) const topic = this.props.topic || '' const payload = this.props.payload if (this.props.connectionId && topic) { this.addMessageToHistory(topic, payload) } } private addMessageToHistory(topic: string, payload?: string) { // Remove duplicates let filteredHistory = this.state.history.filter(e => e.payload !== payload || e.topic !== topic) filteredHistory = filteredHistory.slice(-7) const history: Array = [...filteredHistory, { topic, payload, sent: new Date() }] this.setState({ history }) } private clearTopic = () => { this.props.actions.setTopic('') } private topic() { const topicStr = this.props.topic || '' return (
Topic } endAdornment={} onBlur={this.onTopicBlur} onChange={this.updateTopic} multiline={true} placeholder="example/topic" />
) } private onTopicBlur = (e: React.FocusEvent) => { if (!e.target.value) { this.props.actions.setTopic(undefined) } } private publishButton() { return ( ) } private formatJson = () => { if (this.props.payload) { try { const str = JSON.stringify(JSON.parse(this.props.payload), undefined, ' ') this.updatePayload(str) } catch (error) { this.props.globalActions.showError(`Format error: ${error.message}`) } } } private renderFormatJson() { if (this.props.editorMode !== 'json') { return null } return ( ) } private editorMode() { return (
{this.renderEditorModeSelection()} {this.renderFormatJson()}
{this.publishButton()}
) } private renderEditorModeSelection() { const labelStyle = { margin: '0 8px 0 8px' } return ( } label="raw" labelPlacement="top" /> } label="xml" labelPlacement="top" /> } label="json" labelPlacement="top" /> ) } private onChangeQoS = (event: React.ChangeEvent) => { const value = parseInt(event.target.value, 10) if (value !== 0 && value !== 1 && value !== 2) { return } this.props.actions.setQoS(value) } private publishMode() { const labelStyle = { margin: '0 8px 0 8px' } const itemStyle = { padding: '0' } const tooltipStyle = { textAlign: 'center' as 'center', width: '100%' } const qosSelect = (
0
1
2
) return (
} label="retain" labelPlacement="end" />
) } private history() { const items = this.state.history.reverse().map(message => ({ key: sha1(message.topic + message.payload), title: message.topic, value: message.payload || '', })) return } private didSelectHistoryEntry = (index: number) => { const message = this.state.history[index] this.props.actions.setTopic(message.topic) this.props.actions.setPayload(message.payload) } private editor() { return (
{this.editorMode()} {this.renderEditor()} {this.publishMode()}
) } private renderEditor() { return ( ) } public render() { return (
{this.topic()} {this.editor()} {this.history()}
) } } const mapDispatchToProps = (dispatch: any) => { return { actions: bindActionCreators(publishActions, dispatch), globalActions: bindActionCreators(globalActions, dispatch), } } const mapStateToProps = (state: AppState) => { return { topic: state.publish.topic, payload: state.publish.payload, editorMode: state.publish.editorMode, retain: state.publish.retain, qos: state.publish.qos, } } export default connect(mapStateToProps, mapDispatchToProps)(withTheme(Publish))