Fix delete to work with variable declarations

pull/10616/head
Andrew Watkins 2018-04-24 10:54:17 -07:00
parent 1b80d2a2ff
commit 29fe9d1119
5 changed files with 61 additions and 20 deletions

View File

@ -22,8 +22,9 @@ class BodyBuilder extends PureComponent<Props> {
if (d.funcs) {
return (
<ExpressionNode
bodyID={b.id}
key={b.id}
bodyID={b.id}
declarationID={d.id}
funcNames={this.funcNames}
funcs={d.funcs}
/>

View File

@ -10,12 +10,13 @@ interface Props {
funcNames: any[]
bodyID: string
funcs: Func[]
declarationID?: string
}
// an Expression is a group of one or more functions
class ExpressionNode extends PureComponent<Props> {
public render() {
const {bodyID, funcNames, funcs} = this.props
const {declarationID, bodyID, funcNames, funcs} = this.props
return (
<IFQLContext.Consumer>
{({onDeleteFuncNode, onAddNode, onChangeArg, onGenerateScript}) => {
@ -35,6 +36,7 @@ class ExpressionNode extends PureComponent<Props> {
bodyID={bodyID}
onChangeArg={onChangeArg}
onDelete={onDeleteFuncNode}
declarationID={declarationID}
onGenerateScript={onGenerateScript}
/>
))}

View File

@ -1,12 +1,13 @@
import React, {PureComponent, MouseEvent} from 'react'
import FuncArgs from 'src/ifql/components/FuncArgs'
import {OnChangeArg, Func} from 'src/types/ifql'
import {OnDeleteFuncNode, OnChangeArg, Func} from 'src/types/ifql'
import {ErrorHandling} from 'src/shared/decorators/errors'
interface Props {
func: Func
bodyID: string
onDelete: (funcID: string, bodyID: string) => void
declarationID?: string
onDelete: OnDeleteFuncNode
onChangeArg: OnChangeArg
onGenerateScript: () => void
}
@ -17,6 +18,10 @@ interface State {
@ErrorHandling
export default class FuncNode extends PureComponent<Props, State> {
public static defaultProps: Partial<Props> = {
declarationID: '',
}
constructor(props) {
super(props)
this.state = {
@ -49,7 +54,9 @@ export default class FuncNode extends PureComponent<Props, State> {
}
private handleDelete = (): void => {
this.props.onDelete(this.props.func.id, this.props.bodyID)
const {func, bodyID, declarationID} = this.props
this.props.onDelete({funcID: func.id, bodyID, declarationID})
}
private handleClick = (e: MouseEvent<HTMLElement>): void => {

View File

@ -5,7 +5,7 @@ import {connect} from 'react-redux'
import TimeMachine from 'src/ifql/components/TimeMachine'
import KeyboardShortcuts from 'src/shared/components/KeyboardShortcuts'
import {Suggestion, FlatBody} from 'src/types/ifql'
import {InputArg, Handlers} from 'src/types/ifql'
import {InputArg, Handlers, DeleteFuncNodeArgs} from 'src/types/ifql'
import {bodyNodes} from 'src/ifql/helpers'
import {getSuggestions, getAST} from 'src/ifql/apis'
@ -196,35 +196,60 @@ export class IFQLPage extends PureComponent<Props, State> {
this.getASTResponse(script)
}
private handleDeleteFuncNode = (funcID: string, bodyID: string): void => {
// TODO: export this and test functionality
private handleDeleteFuncNode = (ids: DeleteFuncNodeArgs): void => {
const {funcID, declarationID = '', bodyID} = ids
const script = this.state.body
.map((body, bodyIndex) => {
if (body.id !== bodyID) {
return body.source
}
const funcs = body.funcs.filter(f => f.id !== funcID)
const source = funcs.reduce((acc, f, i) => {
if (i === 0) {
return `${f.source}`
const isLast = bodyIndex === this.state.body.length - 1
if (declarationID) {
const declaration = body.declarations.find(
d => d.id === declarationID
)
if (!declaration) {
return
}
return `${acc}\n\t${f.source}`
}, '')
const isLast = bodyIndex === this.state.body.length - 1
if (isLast) {
return `${source}`
const functions = declaration.funcs.filter(f => f.id !== funcID)
const s = this.funcsToSource(functions)
return `${declaration.name} = ${this.parseLastSource(s, isLast)}`
}
return `${source}\n\n`
const funcs = body.funcs.filter(f => f.id !== funcID)
const source = this.funcsToSource(funcs)
return this.parseLastSource(source, isLast)
})
.join('')
this.getASTResponse(script)
}
// formats the last line of a body string to include two new lines
private parseLastSource = (source: string, isLast: boolean): string => {
if (isLast) {
return `${source}`
}
return `${source}\n\n`
}
// funcsToSource takes a list of funtion nodes and returns an ifql script
private funcsToSource = (funcs): string => {
return funcs.reduce((acc, f, i) => {
if (i === 0) {
return `${f.source}`
}
return `${acc}\n\t${f.source}`
}, '')
}
private getASTResponse = async (script: string) => {
const {links} = this.props

View File

@ -1,5 +1,5 @@
// function definitions
export type OnDeleteFuncNode = (funcID: string, bodyID: string) => void
export type OnDeleteFuncNode = (ids: DeleteFuncNodeArgs) => void
export type OnChangeArg = (inputArg: InputArg) => void
export type OnAddNode = (bodyID: string, funcName: string) => void
export type OnGenerateScript = (script: string) => void
@ -15,6 +15,12 @@ export interface Handlers {
onGenerateScript: OnGenerateScript
}
export interface DeleteFuncNodeArgs {
funcID: string
bodyID: string
declarationID?: string
}
export interface InputArg {
funcID: string
bodyID: string