Add initial ability to handle string argument types

pull/10616/head
Andrew Watkins 2018-04-16 16:56:38 -07:00
parent 45d1c7ad33
commit 809d8718cc
7 changed files with 81 additions and 14 deletions

View File

@ -9,24 +9,34 @@ interface Props {
value: string value: string
type: string type: string
onChangeArg: OnChangeArg onChangeArg: OnChangeArg
onGenerateScript: () => void
} }
class FuncArg extends PureComponent<Props> { class FuncArg extends PureComponent<Props> {
public render() { public render() {
const {argKey, value, type, onChangeArg, funcID} = this.props const {
argKey,
value,
type,
onChangeArg,
funcID,
onGenerateScript,
} = this.props
switch (true) { switch (true) {
case this.isInput: { case this.isInput: {
return ( return (
<FuncArgInput <FuncArgInput
funcID={funcID}
type={type} type={type}
value={value} value={value}
argKey={argKey} argKey={argKey}
funcID={funcID}
onChangeArg={onChangeArg} onChangeArg={onChangeArg}
onGenerateScript={onGenerateScript}
/> />
) )
} }
case types.BOOL === type: { case types.BOOL === type: {
// TODO: make boolean arg component // TODO: make boolean arg component
return ( return (
@ -56,7 +66,14 @@ class FuncArg extends PureComponent<Props> {
private get isInput() { private get isInput() {
const {type} = this.props const {type} = this.props
return type !== types.FUNCTION || types.NIL || types.BOOL || types.INVALID return (
type === types.STRING ||
type === types.DURATION ||
type === types.TIME ||
type === types.INT ||
type === types.REGEXP ||
type === types.UINT
)
} }
} }

View File

@ -1,4 +1,4 @@
import React, {PureComponent, ChangeEvent} from 'react' import React, {PureComponent, ChangeEvent, KeyboardEvent} from 'react'
export type OnChangeArg = (inputArg: InputArg) => void export type OnChangeArg = (inputArg: InputArg) => void
@ -14,6 +14,7 @@ interface Props {
value: string value: string
type: string type: string
onChangeArg: OnChangeArg onChangeArg: OnChangeArg
onGenerateScript: () => void
} }
class FuncArgInput extends PureComponent<Props> { class FuncArgInput extends PureComponent<Props> {
@ -23,22 +24,32 @@ class FuncArgInput extends PureComponent<Props> {
<div> <div>
<label htmlFor={argKey}>{argKey}: </label> <label htmlFor={argKey}>{argKey}: </label>
<input <input
type="text"
name={argKey} name={argKey}
className="form-control input-xs" value={value}
placeholder={type} placeholder={type}
onChange={this.handleChange}
onKeyDown={this.handleKeyDown}
type="text"
className="form-control input-xs"
spellCheck={false} spellCheck={false}
autoComplete="off" autoComplete="off"
value={value}
onChange={this.handleChange}
/> />
</div> </div>
) )
} }
private handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {
if (e.key !== 'Enter') {
return
}
this.props.onGenerateScript()
e.preventDefault()
}
private handleChange = (e: ChangeEvent<HTMLInputElement>) => { private handleChange = (e: ChangeEvent<HTMLInputElement>) => {
const {funcID, argKey} = this.props const {funcID, argKey} = this.props
console.log(this.props)
this.props.onChangeArg({funcID, key: argKey, value: e.target.value}) this.props.onChangeArg({funcID, key: argKey, value: e.target.value})
} }
} }

View File

@ -18,11 +18,12 @@ export interface Func {
interface Props { interface Props {
func: Func func: Func
onChangeArg: OnChangeArg onChangeArg: OnChangeArg
onGenerateScript: () => void
} }
export default class FuncArgs extends PureComponent<Props> { export default class FuncArgs extends PureComponent<Props> {
public render() { public render() {
const {func, onChangeArg} = this.props const {func, onChangeArg, onGenerateScript} = this.props
return ( return (
<div className="func-args"> <div className="func-args">
@ -31,10 +32,11 @@ export default class FuncArgs extends PureComponent<Props> {
<FuncArg <FuncArg
funcID={func.id} funcID={func.id}
key={key} key={key}
type={type}
argKey={key} argKey={key}
value={value} value={value}
type={type}
onChangeArg={onChangeArg} onChangeArg={onChangeArg}
onGenerateScript={onGenerateScript}
/> />
) )
})} })}

View File

@ -7,6 +7,7 @@ interface Props {
func: Func func: Func
onDelete: (id: string) => void onDelete: (id: string) => void
onChangeArg: OnChangeArg onChangeArg: OnChangeArg
onGenerateScript: () => void
} }
interface State { interface State {
@ -22,7 +23,7 @@ export default class FuncNode extends PureComponent<Props, State> {
} }
public render() { public render() {
const {func, onChangeArg} = this.props const {func, onChangeArg, onGenerateScript} = this.props
const {isOpen} = this.state const {isOpen} = this.state
return ( return (
@ -30,7 +31,13 @@ export default class FuncNode extends PureComponent<Props, State> {
<div className="func-node--name" onClick={this.handleClick}> <div className="func-node--name" onClick={this.handleClick}>
<div>{func.name}</div> <div>{func.name}</div>
</div> </div>
{isOpen && <FuncArgs func={func} onChangeArg={onChangeArg} />} {isOpen && (
<FuncArgs
func={func}
onChangeArg={onChangeArg}
onGenerateScript={onGenerateScript}
/>
)}
<div className="btn btn-danger btn-square" onClick={this.handleDelete}> <div className="btn btn-danger btn-square" onClick={this.handleDelete}>
<span className="icon-trash" /> <span className="icon-trash" />
</div> </div>

View File

@ -22,6 +22,7 @@ interface Props {
onSubmitScript: (script: string) => void onSubmitScript: (script: string) => void
onDeleteFuncNode: (id: string) => void onDeleteFuncNode: (id: string) => void
onChangeArg: OnChangeArg onChangeArg: OnChangeArg
onGenerateScript: () => void
} }
class TimeMachine extends PureComponent<Props> { class TimeMachine extends PureComponent<Props> {
@ -30,10 +31,11 @@ class TimeMachine extends PureComponent<Props> {
funcs, funcs,
script, script,
onAddNode, onAddNode,
onChangeArg,
onChangeScript, onChangeScript,
onSubmitScript, onSubmitScript,
onDeleteFuncNode, onDeleteFuncNode,
onChangeArg, onGenerateScript,
} = this.props } = this.props
return ( return (
@ -50,6 +52,7 @@ class TimeMachine extends PureComponent<Props> {
func={f} func={f}
onChangeArg={onChangeArg} onChangeArg={onChangeArg}
onDelete={onDeleteFuncNode} onDelete={onDeleteFuncNode}
onGenerateScript={onGenerateScript}
/> />
))} ))}
<FuncSelector funcs={this.funcNames} onAddNode={onAddNode} /> <FuncSelector funcs={this.funcNames} onAddNode={onAddNode} />

View File

@ -10,6 +10,7 @@ import {Func} from 'src/ifql/components/FuncArgs'
import {InputArg} from 'src/ifql/components/FuncArgInput' import {InputArg} from 'src/ifql/components/FuncArgInput'
import {getSuggestions, getAST} from 'src/ifql/apis' import {getSuggestions, getAST} from 'src/ifql/apis'
import * as argTypes from 'src/ifql/constants/argumentTypes'
interface Links { interface Links {
self: string self: string
@ -75,6 +76,7 @@ export class IFQLPage extends PureComponent<Props, State> {
onSubmitScript={this.getASTResponse} onSubmitScript={this.getASTResponse}
onChangeScript={this.handleChangeScript} onChangeScript={this.handleChangeScript}
onDeleteFuncNode={this.handleDeleteFuncNode} onDeleteFuncNode={this.handleDeleteFuncNode}
onGenerateScript={this.handleGenerateScript}
/> />
</div> </div>
</div> </div>
@ -82,6 +84,10 @@ export class IFQLPage extends PureComponent<Props, State> {
) )
} }
private handleGenerateScript = () => {
this.getASTResponse(this.funcsToScript)
}
private handleChangeArg = ({funcID, key, value}: InputArg) => { private handleChangeArg = ({funcID, key, value}: InputArg) => {
const funcs = this.state.funcs.map(f => { const funcs = this.state.funcs.map(f => {
if (f.id !== funcID) { if (f.id !== funcID) {
@ -102,6 +108,26 @@ export class IFQLPage extends PureComponent<Props, State> {
this.setState({funcs}) this.setState({funcs})
} }
private get funcsToScript(): string {
return this.state.funcs
.map(func => `${func.name}(${this.argsToScript(func.args)})`)
.join('\n\t|> ')
}
private argsToScript(args): string {
const withValues = args.filter(arg => arg.value)
return withValues
.map(({key, value, type}) => {
if (type === argTypes.STRING) {
return `${key}: "${value}"`
}
return `${key}: ${value}`
})
.join(', ')
}
private handleChangeScript = (script: string): void => { private handleChangeScript = (script: string): void => {
this.setState({script}) this.setState({script})
} }

View File

@ -12,6 +12,7 @@ const setup = () => {
onSubmitScript: () => {}, onSubmitScript: () => {},
onDeleteFuncNode: () => {}, onDeleteFuncNode: () => {},
onChangeArg: () => {}, onChangeArg: () => {},
onGenerateScript: () => {},
} }
const wrapper = shallow(<TimeMachine {...props} />) const wrapper = shallow(<TimeMachine {...props} />)