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
parent
7c487cf0c9
commit
562dc839af
|
@ -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}
|
||||
|
|
|
@ -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', '')
|
||||
}
|
||||
}
|
|
@ -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})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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} />
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue