Display arguments and thier values

Co-authored-by: Andrew Watkins <andrew.watkinz@gmail.com>
Co-authored-by: Brandon Farmer <bthesorceror@gmail.com>
pull/10616/head
Andrew Watkins 2018-03-30 15:30:27 -07:00
parent 7c487cf0c9
commit 562dc839af
7 changed files with 125 additions and 23 deletions

View File

@ -10,6 +10,8 @@ import (
"github.com/influxdata/ifql/parser"
)
type Params map[string]string
// SuggestionsResponse provides a list of available IFQL functions
type SuggestionsResponse struct {
Functions []SuggestionResponse `json:"funcs"`
@ -17,8 +19,8 @@ type SuggestionsResponse struct {
// SuggestionResponse provides the parameters available for a given IFQL function
type SuggestionResponse struct {
Name string `json:"name"`
Params map[string]string `json:"params"`
Name string `json:"name"`
Params Params `json:"params"`
}
type ifqlLinks struct {
@ -55,9 +57,18 @@ func (s *Service) IFQLSuggestions(w http.ResponseWriter, r *http.Request) {
return
}
filteredParams := make(Params)
for key, value := range suggestion.Params {
if key == "table" {
continue
}
filteredParams[key] = value
}
functions = append(functions, SuggestionResponse{
Name: name,
Params: suggestion.Params,
Params: filteredParams,
})
}
res := SuggestionsResponse{Functions: functions}

View File

@ -0,0 +1,45 @@
import React, {PureComponent} from 'react'
import _ from 'lodash'
export interface Params {
[key: string]: string
}
export interface Func {
name: string
params: Params
}
interface Arg {
key: string
value: string
}
interface Props {
func: Func
args: Arg[]
}
export default class FuncArgs extends PureComponent<Props> {
public render() {
return (
<div>
{this.paramNames.map(name => (
<div key={name}>
{name} : {this.getArgumentValue(name)}
</div>
))}
</div>
)
}
private get paramNames(): string[] {
const {func: {params}} = this.props
return Object.keys(params)
}
private getArgumentValue(name: string): string {
const {args} = this.props
return _.get(args.find(arg => arg.key === name), 'value', '')
}
}

View File

@ -1,4 +1,14 @@
import React, {PureComponent} from 'react'
import React, {PureComponent, MouseEvent} from 'react'
import FuncArgs from 'src/ifql/components/FuncArgs'
export interface Params {
[key: string]: string
}
export interface Func {
name: string
params: Params
}
interface Arg {
key: string
@ -12,6 +22,7 @@ interface Node {
interface Props {
node: Node
func: Func
}
interface State {
@ -19,13 +30,31 @@ interface State {
}
export default class FuncNode extends PureComponent<Props, State> {
constructor(props) {
super(props)
this.state = {
isOpen: false,
}
}
public render() {
const {node} = this.props
const {node, func} = this.props
const {isOpen} = this.state
return (
<div className="func-node">
<div>{node.name}</div>
<div>
<div className="func-node" onClick={this.handleClick}>
<div>{node.name}</div>
</div>
{isOpen && <FuncArgs args={node.arguments} func={func} />}
</div>
)
}
private handleClick = (e: MouseEvent<HTMLElement>) => {
e.stopPropagation()
const {isOpen} = this.state
this.setState({isOpen: !isOpen})
}
}

View File

@ -1,7 +1,9 @@
import React, {SFC} from 'react'
import React, {PureComponent} from 'react'
import FuncSelector from 'src/ifql/components/FuncSelector'
import FuncNode from 'src/ifql/components/FuncNode'
import {Func} from 'src/ifql/components/FuncNode'
interface Arg {
key: string
value: string
@ -13,20 +15,34 @@ interface NodeProp {
}
interface Props {
funcs: string[]
funcs: Func[]
nodes: NodeProp[]
onAddNode: (name: string) => void
}
const TimeMachine: SFC<Props> = ({funcs, nodes, onAddNode}) => {
return (
<div>
<div className="func-node-container">
{nodes.map((n, i) => <FuncNode key={i} node={n} />)}
<FuncSelector funcs={funcs} onAddNode={onAddNode} />
class TimeMachine extends PureComponent<Props> {
public render() {
const {nodes, onAddNode} = this.props
return (
<div>
<div className="func-node-container">
{nodes.map((n, i) => (
<FuncNode key={i} node={n} func={this.getFunc(n.name)} />
))}
<FuncSelector funcs={this.funcNames} onAddNode={onAddNode} />
</div>
</div>
</div>
)
)
}
private get funcNames() {
return this.props.funcs.map(f => f.name)
}
private getFunc(name) {
return this.props.funcs.find(f => f.name === name)
}
}
export default TimeMachine

View File

@ -5,6 +5,8 @@ import {connect} from 'react-redux'
import TimeMachine from 'src/ifql/components/TimeMachine'
import Walker from 'src/ifql/ast/walker'
import {Func} from 'src/ifql/components/FuncNode'
import {getSuggestions, getAST} from 'src/ifql/apis'
interface Links {
@ -18,7 +20,7 @@ interface Props {
}
interface State {
funcs: string[]
funcs: Func[]
ast: object
query: string
}
@ -29,7 +31,7 @@ export class IFQLPage extends PureComponent<Props, State> {
this.state = {
funcs: [],
ast: null,
query: 'from(db: "telegraf") |> filter() |> range()',
query: 'from(db: "telegraf") |> filter() |> range(start: -15m)',
}
}
@ -38,8 +40,7 @@ export class IFQLPage extends PureComponent<Props, State> {
const {suggestions} = links
try {
const results = await getSuggestions(suggestions)
const funcs = results.map(s => s.name)
const funcs = await getSuggestions(suggestions)
this.setState({funcs})
} catch (error) {
console.error('Could not get function suggestions: ', error)

View File

@ -144,7 +144,7 @@ class Root extends PureComponent<{}, State> {
<Route path="manage-sources" component={ManageSources} />
<Route path="manage-sources/new" component={SourcePage} />
<Route path="manage-sources/:id/edit" component={SourcePage} />
<Route path="ifql" component={IFQLPage} />
<Route path="delorean" component={IFQLPage} />
</Route>
</Route>
<Route path="*" component={NotFound} />

View File

@ -147,7 +147,7 @@ class SideNav extends PureComponent<Props> {
link={`${sourcePrefix}/ifql`}
location={location}
>
<NavHeader link={`${sourcePrefix}/ifql`} title="IFQL Builder" />
<NavHeader link={`${sourcePrefix}/delorean`} title="Time Machine" />
</NavBlock>
</FeatureFlag>
</nav>