Add clear button to topic search
This commit is contained in:
@@ -5,16 +5,19 @@ import { rendererEvents, addMqttConnectionEvent, makeConnectionStateEvent, remov
|
||||
import { AppState } from '../reducers'
|
||||
import * as q from '../../../backend/src/Model'
|
||||
import { showTree } from './Tree'
|
||||
import * as url from 'url'
|
||||
|
||||
export const connect = (options: MqttOptions, connectionId: string) => (dispatch: Dispatch<any>, getState: () => AppState) => {
|
||||
dispatch(connecting(connectionId))
|
||||
rendererEvents.emit(addMqttConnectionEvent, { options, id: connectionId })
|
||||
const event = makeConnectionStateEvent(connectionId)
|
||||
const host = url.parse(options.url).hostname
|
||||
|
||||
rendererEvents.subscribe(event, (dataSourceState) => {
|
||||
if (dataSourceState.connected) {
|
||||
const tree = new q.Tree()
|
||||
tree.updateWithConnection(rendererEvents, connectionId)
|
||||
dispatch(connected(tree))
|
||||
dispatch(connected(tree, host!))
|
||||
dispatch(showTree(tree))
|
||||
} else if (dataSourceState.error) {
|
||||
dispatch(showError(dataSourceState.error))
|
||||
@@ -23,8 +26,9 @@ export const connect = (options: MqttOptions, connectionId: string) => (dispatch
|
||||
})
|
||||
}
|
||||
|
||||
export const connected: (tree: q.Tree) => Action = (tree: q.Tree) => ({
|
||||
export const connected: (tree: q.Tree, host: string) => Action = (tree: q.Tree, host: string) => ({
|
||||
tree,
|
||||
host,
|
||||
type: ActionTypes.CONNECTION_SET_CONNECTED,
|
||||
})
|
||||
|
||||
|
||||
@@ -26,23 +26,20 @@ export const setTopicOrder = (topicOrder: TopicOrder = TopicOrder.none): Action
|
||||
}
|
||||
|
||||
export const filterTopics = (filterStr: string) => (dispatch: Dispatch<any>, getState: () => AppState) => {
|
||||
const topicFilter = filterStr.toLowerCase()
|
||||
const { tree } = getState().connection
|
||||
|
||||
dispatch({
|
||||
topicFilter,
|
||||
topicFilter: filterStr,
|
||||
type: ActionTypes.SETTINGS_FILTER_TOPICS,
|
||||
})
|
||||
|
||||
const { tree } = getState().connection
|
||||
if (!tree) {
|
||||
return
|
||||
}
|
||||
|
||||
if (!topicFilter) {
|
||||
if (!filterStr || !tree) {
|
||||
dispatch(showTree(tree))
|
||||
return
|
||||
}
|
||||
|
||||
const topicFilter = filterStr.toLowerCase()
|
||||
|
||||
const nodeFilter = (node: q.TreeNode): boolean => {
|
||||
const topicMatches = node.path().toLowerCase().indexOf(topicFilter) !== -1
|
||||
if (topicMatches) {
|
||||
|
||||
@@ -32,6 +32,7 @@ import Clear from '@material-ui/icons/Clear'
|
||||
import { bindActionCreators } from 'redux'
|
||||
import { connect } from 'react-redux'
|
||||
import { publishActions } from '../../../actions'
|
||||
import ClearAdornment from '../../helper/ClearAdornment';
|
||||
|
||||
interface Props {
|
||||
node?: q.TreeNode
|
||||
@@ -114,7 +115,7 @@ class Publish extends React.Component<Props, State> {
|
||||
id="publish-topic"
|
||||
value={topicStr}
|
||||
startAdornment={<span/>}
|
||||
endAdornment={<IconButton style={{ padding: '4px' }} onClick={this.clearTopic}><Clear style={{ fontSize: '14px' }} /></IconButton>}
|
||||
endAdornment={<ClearAdornment action={this.clearTopic} value={topicStr} />}
|
||||
onBlur={this.onTopicBlur}
|
||||
onChange={this.updateTopic}
|
||||
multiline={true}
|
||||
|
||||
@@ -12,6 +12,7 @@ import { connect } from 'react-redux'
|
||||
import { fade } from '@material-ui/core/styles/colorManipulator'
|
||||
import { settingsActions, connectionActions } from '../actions'
|
||||
import { AppState } from '../reducers'
|
||||
import ClearAdornment from './helper/ClearAdornment';
|
||||
|
||||
const styles: StyleRulesCallback = theme => ({
|
||||
title: {
|
||||
@@ -36,7 +37,7 @@ const styles: StyleRulesCallback = theme => ({
|
||||
},
|
||||
},
|
||||
searchIcon: {
|
||||
width: theme.spacing.unit * 9,
|
||||
width: theme.spacing.unit * 8,
|
||||
height: '100%',
|
||||
position: 'absolute',
|
||||
pointerEvents: 'none',
|
||||
@@ -100,7 +101,7 @@ class TitleBar extends React.Component<Props, {}> {
|
||||
}
|
||||
|
||||
private renderSearch() {
|
||||
const { classes } = this.props
|
||||
const { classes, topicFilter } = this.props
|
||||
|
||||
return (
|
||||
<div className={classes.search}>
|
||||
@@ -108,15 +109,20 @@ class TitleBar extends React.Component<Props, {}> {
|
||||
<Search />
|
||||
</div>
|
||||
<InputBase
|
||||
value={this.props.topicFilter}
|
||||
value={topicFilter}
|
||||
onChange={this.onFilterChange}
|
||||
placeholder="Search…"
|
||||
endAdornment={<div style={{ width: '24px', paddingRight: '8px' }}><ClearAdornment action={this.clearFilter} value={topicFilter} /></div>}
|
||||
classes={{ root: classes.inputRoot, input: classes.inputInput }}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
private clearFilter = () => {
|
||||
this.props.actions.settings.filterTopics('')
|
||||
}
|
||||
|
||||
private onFilterChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
this.props.actions.settings.filterTopics(event.target.value)
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ interface Props {
|
||||
connectionId?: string
|
||||
tree?: q.Tree
|
||||
filter: string
|
||||
host?: string
|
||||
}
|
||||
|
||||
class Tree extends React.Component<Props, {}> {
|
||||
@@ -90,7 +91,7 @@ class Tree extends React.Component<Props, {}> {
|
||||
animateChages={true}
|
||||
isRoot={true}
|
||||
treeNode={tree}
|
||||
name={'"root"'}
|
||||
name={this.props.host}
|
||||
lastUpdate={tree.lastUpdate}
|
||||
collapsed={false}
|
||||
performanceCallback={this.performanceCallback}
|
||||
@@ -109,6 +110,7 @@ const mapStateToProps = (state: AppState) => {
|
||||
autoExpandLimit: state.settings.autoExpandLimit,
|
||||
tree: state.tree.tree,
|
||||
filter: state.tree.filter,
|
||||
host: state.connection.host,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
25
app/src/components/helper/ClearAdornment.tsx
Normal file
25
app/src/components/helper/ClearAdornment.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import * as React from 'react'
|
||||
import { IconButton } from '@material-ui/core'
|
||||
import Clear from '@material-ui/icons/Clear'
|
||||
|
||||
interface Props {
|
||||
value?: string
|
||||
action: any
|
||||
style?: React.CSSProperties
|
||||
}
|
||||
|
||||
class ClearAdornment extends React.Component<Props, {}> {
|
||||
public render() {
|
||||
if (this.props.value) {
|
||||
return (
|
||||
<IconButton style={{ ...this.props.style, padding: '1px' }} onClick={this.props.action}>
|
||||
<Clear style={{ fontSize: '16px' }} />
|
||||
</IconButton>
|
||||
)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
export default ClearAdornment
|
||||
@@ -4,6 +4,7 @@ import * as q from '../../../backend/src/Model'
|
||||
import { MqttOptions } from '../../../backend/src/DataSource'
|
||||
|
||||
export interface ConnectionState {
|
||||
host?: string
|
||||
tree?: q.Tree
|
||||
connectionOptions?: MqttOptions
|
||||
connectionId?: string
|
||||
@@ -28,6 +29,7 @@ export interface SetConnecting {
|
||||
|
||||
export interface SetConnected {
|
||||
type: ActionTypes.CONNECTION_SET_CONNECTED
|
||||
host: string
|
||||
tree: q.Tree
|
||||
}
|
||||
|
||||
@@ -52,7 +54,7 @@ export const connectionReducer = createReducer(initialState, {
|
||||
CONNECTION_SET_SHOW_ERROR: showError,
|
||||
})
|
||||
|
||||
function setConnecting(state: ConnectionState, action: SetConnecting) {
|
||||
function setConnecting(state: ConnectionState, action: SetConnecting): ConnectionState {
|
||||
return {
|
||||
...state,
|
||||
connecting: true,
|
||||
@@ -61,18 +63,20 @@ function setConnecting(state: ConnectionState, action: SetConnecting) {
|
||||
}
|
||||
}
|
||||
|
||||
function setConnected(state: ConnectionState, action: SetConnected) {
|
||||
function setConnected(state: ConnectionState, action: SetConnected): ConnectionState {
|
||||
return {
|
||||
...state,
|
||||
host: action.host,
|
||||
connecting: false,
|
||||
connected: true,
|
||||
tree: action.tree,
|
||||
}
|
||||
}
|
||||
|
||||
function setDisconnected(state: ConnectionState, action: SetDisconnected) {
|
||||
function setDisconnected(state: ConnectionState, action: SetDisconnected): ConnectionState {
|
||||
return {
|
||||
...state,
|
||||
host: undefined,
|
||||
connecting: false,
|
||||
connected: false,
|
||||
connectionId: undefined,
|
||||
|
||||
Reference in New Issue
Block a user