feature(chronograf): use sources instead of services for flux builder

Co-authored-by: Andrew Watkins <andrew.watkinz@gmail.com>
Co-authored-by: Michael Desa <mjdesa@gmail.com>
pull/10616/head
Andrew Watkins 2018-07-26 15:33:44 -07:00
parent c42e4d98e0
commit 2d7f54de2a
33 changed files with 217 additions and 331 deletions

View File

@ -49,16 +49,9 @@ interface GetTimeSeriesResult {
} }
export const getTimeSeries = async ( export const getTimeSeries = async (
service: Service, url: string, // query URI
script: string script: string
): Promise<GetTimeSeriesResult> => { ): Promise<GetTimeSeriesResult> => {
const and = encodeURIComponent('&')
const mark = encodeURIComponent('?')
const garbage = script.replace(/\s/g, '') // server cannot handle whitespace
const url = `${window.basepath}${
service.links.proxy
}?path=/v1/query${mark}orgName=defaulorgname${and}q=${garbage}`
let responseBody: string let responseBody: string
let responseByteLength: number let responseByteLength: number
@ -69,7 +62,11 @@ export const getTimeSeries = async (
// seems to be broken at the moment. We might use this option instead of // seems to be broken at the moment. We might use this option instead of
// the `fetch` API in the future, if it is ever fixed. See // the `fetch` API in the future, if it is ever fixed. See
// https://github.com/axios/axios/issues/1491. // https://github.com/axios/axios/issues/1491.
const resp = await fetch(url, {method: 'POST'}) const resp = await fetch(url, {
method: 'POST',
body: JSON.stringify({script}),
})
const {body, byteLength} = await decodeFluxRespWithLimit(resp) const {body, byteLength} = await decodeFluxRespWithLimit(resp)
responseBody = body responseBody = body

View File

@ -8,11 +8,9 @@ import FuncSelector from 'src/flux/components/FuncSelector'
import BodyDelete from 'src/flux/components/BodyDelete' import BodyDelete from 'src/flux/components/BodyDelete'
import {funcNames} from 'src/flux/constants' import {funcNames} from 'src/flux/constants'
import {Service} from 'src/types'
import {Body, Suggestion} from 'src/types/flux' import {Body, Suggestion} from 'src/types/flux'
interface Props { interface Props {
service: Service
body: Body[] body: Body[]
suggestions: Suggestion[] suggestions: Suggestion[]
onAppendFrom: () => void onAppendFrom: () => void

View File

@ -1,16 +1,22 @@
// Libraries
import React, {PureComponent} from 'react' import React, {PureComponent} from 'react'
import {NotificationContext} from 'src/flux/containers/CheckServices' // Components
import DatabaseListItem from 'src/flux/components/DatabaseListItem' import DatabaseListItem from 'src/flux/components/DatabaseListItem'
// APIs
import {showDatabases} from 'src/shared/apis/metaQuery' import {showDatabases} from 'src/shared/apis/metaQuery'
import showDatabasesParser from 'src/shared/parsing/showDatabases' import showDatabasesParser from 'src/shared/parsing/showDatabases'
// Types
import {Source} from 'src/types'
import {NotificationAction} from 'src/types/notifications'
import {ErrorHandling} from 'src/shared/decorators/errors' import {ErrorHandling} from 'src/shared/decorators/errors'
import {Service} from 'src/types'
interface Props { interface Props {
service: Service source: Source
notify: NotificationAction
} }
interface State { interface State {
@ -32,10 +38,10 @@ class DatabaseList extends PureComponent<Props, State> {
} }
public async getDatabases() { public async getDatabases() {
const {service} = this.props const {source} = this.props
try { try {
const {data} = await showDatabases(`${service.links.source}/proxy`) const {data} = await showDatabases(`${source.links.self}/proxy`)
const {databases} = showDatabasesParser(data) const {databases} = showDatabasesParser(data)
const sorted = databases.sort() const sorted = databases.sort()
@ -47,15 +53,11 @@ class DatabaseList extends PureComponent<Props, State> {
public render() { public render() {
const {databases} = this.state const {databases} = this.state
const {service} = this.props const {source, notify} = this.props
return databases.map(db => { return databases.map(db => {
return ( return (
<NotificationContext.Consumer key={db}> <DatabaseListItem key={db} db={db} source={source} notify={notify} />
{({notify}) => (
<DatabaseListItem db={db} service={service} notify={notify} />
)}
</NotificationContext.Consumer>
) )
}) })
} }

View File

@ -10,11 +10,11 @@ import {
notifyCopyToClipboardFailed, notifyCopyToClipboardFailed,
} from 'src/shared/copy/notifications' } from 'src/shared/copy/notifications'
import {Service, NotificationAction} from 'src/types' import {Source, NotificationAction} from 'src/types'
interface Props { interface Props {
db: string db: string
service: Service source: Source
notify: NotificationAction notify: NotificationAction
} }
@ -35,10 +35,10 @@ class DatabaseListItem extends PureComponent<Props, State> {
} }
public async componentDidMount() { public async componentDidMount() {
const {db, service} = this.props const {db, source} = this.props
try { try {
const response = await fetchTagKeys(service, db, []) const response = await fetchTagKeys(source, db, [])
const tags = parseValuesColumn(response) const tags = parseValuesColumn(response)
this.setState({tags}) this.setState({tags})
} catch (error) { } catch (error) {
@ -82,7 +82,7 @@ class DatabaseListItem extends PureComponent<Props, State> {
} }
private get filterAndTagList(): JSX.Element { private get filterAndTagList(): JSX.Element {
const {db, service} = this.props const {db, source, notify} = this.props
const {isOpen, searchTerm} = this.state const {isOpen, searchTerm} = this.state
return ( return (
@ -99,7 +99,13 @@ class DatabaseListItem extends PureComponent<Props, State> {
onChange={this.onSearch} onChange={this.onSearch}
/> />
</div> </div>
<TagList db={db} service={service} tags={this.tags} filter={[]} /> <TagList
db={db}
source={source}
tags={this.tags}
filter={[]}
notify={notify}
/>
</div> </div>
) )
} }

View File

@ -54,7 +54,7 @@ class ExpressionNode extends PureComponent<Props, State> {
onChangeArg, onChangeArg,
onGenerateScript, onGenerateScript,
onToggleYield, onToggleYield,
service, source,
data, data,
scriptUpToYield, scriptUpToYield,
}: Context) => { }: Context) => {
@ -84,7 +84,7 @@ class ExpressionNode extends PureComponent<Props, State> {
func={func} func={func}
funcs={funcs} funcs={funcs}
bodyID={bodyID} bodyID={bodyID}
service={service} source={source}
onChangeArg={onChangeArg} onChangeArg={onChangeArg}
onDelete={onDeleteFuncNode} onDelete={onDeleteFuncNode}
onToggleYield={onToggleYield} onToggleYield={onToggleYield}
@ -125,7 +125,7 @@ class ExpressionNode extends PureComponent<Props, State> {
data={data} data={data}
script={script} script={script}
bodyID={bodyID} bodyID={bodyID}
service={service} source={source}
declarationID={declarationID} declarationID={declarationID}
/> />
</Fragment> </Fragment>

View File

@ -7,7 +7,7 @@ import FilterTagList from 'src/flux/components/FilterTagList'
import Walker from 'src/flux/ast/walker' import Walker from 'src/flux/ast/walker'
import {makeCancelable} from 'src/utils/promises' import {makeCancelable} from 'src/utils/promises'
import {Service} from 'src/types' import {Source} from 'src/types'
import {Links, OnChangeArg, Func, FilterNode} from 'src/types/flux' import {Links, OnChangeArg, Func, FilterNode} from 'src/types/flux'
import {WrappedCancelablePromise} from 'src/types/promises' import {WrappedCancelablePromise} from 'src/types/promises'
@ -19,7 +19,7 @@ interface Props {
declarationID: string declarationID: string
onChangeArg: OnChangeArg onChangeArg: OnChangeArg
db: string db: string
service: Service source: Source
onGenerateScript: () => void onGenerateScript: () => void
} }
@ -80,7 +80,7 @@ class FilterArgs extends PureComponent<Props, State> {
public render() { public render() {
const { const {
db, db,
service, source,
onChangeArg, onChangeArg,
func, func,
bodyID, bodyID,
@ -92,7 +92,7 @@ class FilterArgs extends PureComponent<Props, State> {
return ( return (
<FilterTagList <FilterTagList
db={db} db={db}
service={service} source={source}
tags={this.state.tagKeys} tags={this.state.tagKeys}
filter={[]} filter={[]}
onChangeArg={onChangeArg} onChangeArg={onChangeArg}
@ -106,9 +106,9 @@ class FilterArgs extends PureComponent<Props, State> {
} }
private getTagKeys(): Promise<string> { private getTagKeys(): Promise<string> {
const {db, service} = this.props const {db, source} = this.props
this.fetchTagKeysResponse = makeCancelable(fetchTagKeys(service, db, [])) this.fetchTagKeysResponse = makeCancelable(fetchTagKeys(source, db, []))
return this.fetchTagKeysResponse.promise return this.fetchTagKeysResponse.promise
} }

View File

@ -1,7 +1,6 @@
import React, {PureComponent, MouseEvent} from 'react' import React, {PureComponent, MouseEvent} from 'react'
import _ from 'lodash' import _ from 'lodash'
import {SchemaFilter, Service} from 'src/types'
import { import {
OnChangeArg, OnChangeArg,
Func, Func,
@ -16,9 +15,11 @@ import FilterTagListItem from 'src/flux/components/FilterTagListItem'
import FancyScrollbar from '../../shared/components/FancyScrollbar' import FancyScrollbar from '../../shared/components/FancyScrollbar'
import {getDeep} from 'src/utils/wrappers' import {getDeep} from 'src/utils/wrappers'
import {SchemaFilter, Source} from 'src/types'
interface Props { interface Props {
db: string db: string
service: Service source: Source
tags: string[] tags: string[]
filter: SchemaFilter[] filter: SchemaFilter[]
onChangeArg: OnChangeArg onChangeArg: OnChangeArg
@ -130,7 +131,7 @@ export default class FilterTagList extends PureComponent<Props> {
public render() { public render() {
const { const {
db, db,
service, source,
tags, tags,
filter, filter,
bodyID, bodyID,
@ -173,7 +174,7 @@ export default class FilterTagList extends PureComponent<Props> {
operator={this.operator(t)} operator={this.operator(t)}
onChangeValue={this.handleChangeValue} onChangeValue={this.handleChangeValue}
onSetEquality={this.handleSetEquality} onSetEquality={this.handleSetEquality}
service={service} source={source}
filter={filter} filter={filter}
/> />
))} ))}

View File

@ -7,7 +7,6 @@ import React, {
import _ from 'lodash' import _ from 'lodash'
import {Service, SchemaFilter, RemoteDataState} from 'src/types'
import {tagValues as fetchTagValues} from 'src/shared/apis/flux/metaQueries' import {tagValues as fetchTagValues} from 'src/shared/apis/flux/metaQueries'
import {explorer} from 'src/flux/constants' import {explorer} from 'src/flux/constants'
import { import {
@ -20,6 +19,8 @@ import FilterTagValueList from 'src/flux/components/FilterTagValueList'
import LoaderSkeleton from 'src/flux/components/LoaderSkeleton' import LoaderSkeleton from 'src/flux/components/LoaderSkeleton'
import LoadingSpinner from 'src/flux/components/LoadingSpinner' import LoadingSpinner from 'src/flux/components/LoadingSpinner'
import {Source, SchemaFilter, RemoteDataState} from 'src/types'
interface Props { interface Props {
tagKey: string tagKey: string
onSetEquality: SetEquality onSetEquality: SetEquality
@ -27,7 +28,7 @@ interface Props {
conditions: FilterTagCondition[] conditions: FilterTagCondition[]
operator: string operator: string
db: string db: string
service: Service source: Source
filter: SchemaFilter[] filter: SchemaFilter[]
} }
@ -89,7 +90,7 @@ export default class FilterTagListItem extends PureComponent<Props, State> {
} }
public render() { public render() {
const {tagKey, db, service, filter} = this.props const {tagKey, db, filter} = this.props
const {tagValues, searchTerm, loadingMore, count, limit} = this.state const {tagValues, searchTerm, loadingMore, count, limit} = this.state
const selectedValues = this.props.conditions.map(c => c.value) const selectedValues = this.props.conditions.map(c => c.value)
@ -132,16 +133,15 @@ export default class FilterTagListItem extends PureComponent<Props, State> {
{!this.isLoading && ( {!this.isLoading && (
<FilterTagValueList <FilterTagValueList
db={db} db={db}
service={service} tagKey={tagKey}
filter={filter}
values={tagValues} values={tagValues}
selectedValues={selectedValues} selectedValues={selectedValues}
tagKey={tagKey} loadMoreCount={this.loadMoreCount}
shouldShowMoreValues={limit < count}
onChangeValue={this.props.onChangeValue} onChangeValue={this.props.onChangeValue}
filter={filter}
onLoadMoreValues={this.handleLoadMoreValues} onLoadMoreValues={this.handleLoadMoreValues}
isLoadingMoreValues={loadingMore === RemoteDataState.Loading} isLoadingMoreValues={loadingMore === RemoteDataState.Loading}
shouldShowMoreValues={limit < count}
loadMoreCount={this.loadMoreCount}
/> />
)} )}
</div> </div>
@ -236,10 +236,10 @@ export default class FilterTagListItem extends PureComponent<Props, State> {
} }
private getTagValues = async () => { private getTagValues = async () => {
const {db, service, tagKey, filter} = this.props const {db, source, tagKey, filter} = this.props
const {searchTerm, limit} = this.state const {searchTerm, limit} = this.state
const response = await fetchTagValues({ const response = await fetchTagValues({
service, source,
db, db,
filter, filter,
tagKey, tagKey,
@ -271,11 +271,11 @@ export default class FilterTagListItem extends PureComponent<Props, State> {
} }
private async getCount() { private async getCount() {
const {service, db, filter, tagKey} = this.props const {source, db, filter, tagKey} = this.props
const {limit, searchTerm} = this.state const {limit, searchTerm} = this.state
try { try {
const response = await fetchTagValues({ const response = await fetchTagValues({
service, source,
db, db,
filter, filter,
tagKey, tagKey,

View File

@ -3,11 +3,10 @@ import _ from 'lodash'
import FilterTagValueListItem from 'src/flux/components/FilterTagValueListItem' import FilterTagValueListItem from 'src/flux/components/FilterTagValueListItem'
import LoadingSpinner from 'src/flux/components/LoadingSpinner' import LoadingSpinner from 'src/flux/components/LoadingSpinner'
import {Service, SchemaFilter} from 'src/types' import {SchemaFilter} from 'src/types'
import {SetFilterTagValue} from 'src/types/flux' import {SetFilterTagValue} from 'src/types/flux'
interface Props { interface Props {
service: Service
db: string db: string
tagKey: string tagKey: string
values: string[] values: string[]

View File

@ -1,47 +0,0 @@
import React, {PureComponent} from 'react'
import PageHeader from 'src/reusable_ui/components/page_layout/PageHeader'
import {Service} from 'src/types'
interface Props {
service: Service
services: Service[]
onGoToEditFlux: (service: Service) => void
}
class FluxHeader extends PureComponent<Props> {
constructor(props: Props) {
super(props)
}
public render() {
return (
<>
<PageHeader
titleText="Flux Editor"
fullWidth={true}
optionsComponents={this.optionsComponents}
/>
</>
)
}
private get optionsComponents(): JSX.Element {
return (
<button
onClick={this.handleGoToEditFlux}
className="btn btn-sm btn-default"
>
Edit Connection
</button>
)
}
private handleGoToEditFlux = () => {
const {service, onGoToEditFlux} = this.props
onGoToEditFlux(service)
}
}
export default FluxHeader

View File

@ -5,7 +5,8 @@ import showDatabasesParser from 'src/shared/parsing/showDatabases'
import Dropdown from 'src/shared/components/Dropdown' import Dropdown from 'src/shared/components/Dropdown'
import {OnChangeArg} from 'src/types/flux' import {OnChangeArg} from 'src/types/flux'
import {Service} from 'src/types'
import {Source} from 'src/types'
interface Props { interface Props {
funcID: string funcID: string
@ -14,7 +15,7 @@ interface Props {
bodyID: string bodyID: string
declarationID: string declarationID: string
onChangeArg: OnChangeArg onChangeArg: OnChangeArg
service: Service source: Source
} }
interface State { interface State {
@ -34,10 +35,11 @@ class FromDatabaseDropdown extends PureComponent<Props, State> {
} }
public async componentDidMount() { public async componentDidMount() {
const {service} = this.props const {source} = this.props
try { try {
const {data} = await showDatabases(`${service.links.source}/proxy`) // (watts): TODO: hit actual showDatabases API
const {data} = await showDatabases(source.links.proxy)
const {databases} = showDatabasesParser(data) const {databases} = showDatabasesParser(data)
const sorted = databases.sort() const sorted = databases.sort()

View File

@ -9,10 +9,11 @@ import FromDatabaseDropdown from 'src/flux/components/FromDatabaseDropdown'
import {funcNames, argTypes} from 'src/flux/constants' import {funcNames, argTypes} from 'src/flux/constants'
import {OnChangeArg, Arg, OnGenerateScript} from 'src/types/flux' import {OnChangeArg, Arg, OnGenerateScript} from 'src/types/flux'
import {Service} from 'src/types'
import {Source} from 'src/types'
interface Props { interface Props {
service: Service source: Source
funcName: string funcName: string
funcID: string funcID: string
argKey: string argKey: string
@ -34,7 +35,7 @@ class FuncArg extends PureComponent<Props> {
type, type,
bodyID, bodyID,
funcID, funcID,
service, source,
funcName, funcName,
onChangeArg, onChangeArg,
declarationID, declarationID,
@ -44,7 +45,7 @@ class FuncArg extends PureComponent<Props> {
if (funcName === funcNames.FROM) { if (funcName === funcNames.FROM) {
return ( return (
<FromDatabaseDropdown <FromDatabaseDropdown
service={service} source={source}
argKey={argKey} argKey={argKey}
funcID={funcID} funcID={funcID}
value={this.value} value={this.value}

View File

@ -6,12 +6,12 @@ import {Func, OnGenerateScript} from 'src/types/flux'
import {funcNames} from 'src/flux/constants' import {funcNames} from 'src/flux/constants'
import JoinArgs from 'src/flux/components/JoinArgs' import JoinArgs from 'src/flux/components/JoinArgs'
import FilterArgs from 'src/flux/components/FilterArgs' import FilterArgs from 'src/flux/components/FilterArgs'
import {Service} from 'src/types' import {Source} from 'src/types'
import {getDeep} from 'src/utils/wrappers' import {getDeep} from 'src/utils/wrappers'
interface Props { interface Props {
func: Func func: Func
service: Service source: Source
bodyID: string bodyID: string
onChangeArg: OnChangeArg onChangeArg: OnChangeArg
declarationID: string declarationID: string
@ -53,7 +53,7 @@ export default class FuncArgs extends PureComponent<Props> {
const { const {
func, func,
bodyID, bodyID,
service, source,
onChangeArg, onChangeArg,
declarationID, declarationID,
onGenerateScript, onGenerateScript,
@ -71,7 +71,7 @@ export default class FuncArgs extends PureComponent<Props> {
bodyID={bodyID} bodyID={bodyID}
funcID={funcID} funcID={funcID}
funcName={funcName} funcName={funcName}
service={service} source={source}
onChangeArg={onChangeArg} onChangeArg={onChangeArg}
declarationID={declarationID} declarationID={declarationID}
onGenerateScript={onGenerateScript} onGenerateScript={onGenerateScript}
@ -83,7 +83,7 @@ export default class FuncArgs extends PureComponent<Props> {
const { const {
func, func,
bodyID, bodyID,
service, source,
onChangeArg, onChangeArg,
declarationID, declarationID,
onGenerateScript, onGenerateScript,
@ -98,7 +98,7 @@ export default class FuncArgs extends PureComponent<Props> {
declarationID={declarationID} declarationID={declarationID}
onChangeArg={onChangeArg} onChangeArg={onChangeArg}
onGenerateScript={onGenerateScript} onGenerateScript={onGenerateScript}
service={service} source={source}
db={'telegraf'} db={'telegraf'}
/> />
) )

View File

@ -15,12 +15,12 @@ import {
} from 'src/types/flux' } from 'src/types/flux'
import {ErrorHandling} from 'src/shared/decorators/errors' import {ErrorHandling} from 'src/shared/decorators/errors'
import {Service} from 'src/types' import {Source} from 'src/types'
interface Props { interface Props {
func: Func func: Func
funcs: Func[] funcs: Func[]
service: Service source: Source
bodyID: string bodyID: string
index: number index: number
declarationID?: string declarationID?: string
@ -80,7 +80,7 @@ export default class FuncNode extends PureComponent<Props, State> {
const { const {
func, func,
bodyID, bodyID,
service, source,
isYielding, isYielding,
onChangeArg, onChangeArg,
declarationID, declarationID,
@ -97,7 +97,7 @@ export default class FuncNode extends PureComponent<Props, State> {
<FuncArgs <FuncArgs
func={func} func={func}
bodyID={bodyID} bodyID={bodyID}
service={service} source={source}
onChangeArg={onChangeArg} onChangeArg={onChangeArg}
declarationID={declarationID} declarationID={declarationID}
onGenerateScript={onGenerateScript} onGenerateScript={onGenerateScript}

View File

@ -1,24 +1,39 @@
// Libraries
import React, {PureComponent} from 'react' import React, {PureComponent} from 'react'
import {connect} from 'react-redux'
// Components
import DatabaseList from 'src/flux/components/DatabaseList' import DatabaseList from 'src/flux/components/DatabaseList'
import FancyScrollbar from 'src/shared/components/FancyScrollbar' import FancyScrollbar from 'src/shared/components/FancyScrollbar'
import {Service} from 'src/types'
// Actions
import {notify as notifyAction} from 'src/shared/actions/notifications'
// Types
import {Source} from 'src/types'
import {NotificationAction} from 'src/types/notifications'
interface Props { interface Props {
service: Service source: Source
notify: NotificationAction
} }
class SchemaExplorer extends PureComponent<Props> { class SchemaExplorer extends PureComponent<Props> {
public render() { public render() {
const {service} = this.props const {source, notify} = this.props
return ( return (
<div className="flux-schema-explorer"> <div className="flux-schema-explorer">
<FancyScrollbar> <FancyScrollbar>
<DatabaseList service={service} /> <DatabaseList source={source} notify={notify} />
</FancyScrollbar> </FancyScrollbar>
</div> </div>
) )
} }
} }
export default SchemaExplorer const mdtp = {
notify: notifyAction,
}
export default connect(null, mdtp)(SchemaExplorer)

View File

@ -1,36 +1,34 @@
import React, {PureComponent, MouseEvent} from 'react' import React, {PureComponent, MouseEvent} from 'react'
import TagListItem from 'src/flux/components/TagListItem' import TagListItem from 'src/flux/components/TagListItem'
import {NotificationContext} from 'src/flux/containers/CheckServices'
import {SchemaFilter, Service} from 'src/types' import {SchemaFilter, Source} from 'src/types'
import {NotificationAction} from 'src/types/notifications'
interface Props { interface Props {
db: string db: string
service: Service source: Source
tags: string[] tags: string[]
filter: SchemaFilter[] filter: SchemaFilter[]
notify: NotificationAction
} }
export default class TagList extends PureComponent<Props> { export default class TagList extends PureComponent<Props> {
public render() { public render() {
const {db, service, tags, filter} = this.props const {db, source, tags, filter, notify} = this.props
if (tags.length) { if (tags.length) {
return ( return (
<> <>
{tags.map(t => ( {tags.map(t => (
<NotificationContext.Consumer key={t}> <TagListItem
{({notify}) => ( key={t}
<TagListItem db={db}
db={db} tagKey={t}
tagKey={t} source={source}
service={service} filter={filter}
filter={filter} notify={notify}
notify={notify} />
/>
)}
</NotificationContext.Consumer>
))} ))}
</> </>
) )

View File

@ -1,31 +1,37 @@
// Libraries
import React, { import React, {
PureComponent, PureComponent,
CSSProperties, CSSProperties,
ChangeEvent, ChangeEvent,
MouseEvent, MouseEvent,
} from 'react' } from 'react'
import _ from 'lodash' import _ from 'lodash'
import {CopyToClipboard} from 'react-copy-to-clipboard' import {CopyToClipboard} from 'react-copy-to-clipboard'
import {Service, SchemaFilter, RemoteDataState} from 'src/types' // Components
import {tagValues as fetchTagValues} from 'src/shared/apis/flux/metaQueries'
import {explorer} from 'src/flux/constants'
import parseValuesColumn from 'src/shared/parsing/flux/values'
import TagValueList from 'src/flux/components/TagValueList' import TagValueList from 'src/flux/components/TagValueList'
import LoaderSkeleton from 'src/flux/components/LoaderSkeleton' import LoaderSkeleton from 'src/flux/components/LoaderSkeleton'
import LoadingSpinner from 'src/flux/components/LoadingSpinner' import LoadingSpinner from 'src/flux/components/LoadingSpinner'
// APIs
import {tagValues as fetchTagValues} from 'src/shared/apis/flux/metaQueries'
import parseValuesColumn from 'src/shared/parsing/flux/values'
// Constants
import { import {
notifyCopyToClipboardSuccess, notifyCopyToClipboardSuccess,
notifyCopyToClipboardFailed, notifyCopyToClipboardFailed,
} from 'src/shared/copy/notifications' } from 'src/shared/copy/notifications'
import {explorer} from 'src/flux/constants'
// Types
import {NotificationAction} from 'src/types' import {NotificationAction} from 'src/types'
import {Source, SchemaFilter, RemoteDataState} from 'src/types'
interface Props { interface Props {
tagKey: string tagKey: string
db: string db: string
service: Service source: Source
filter: SchemaFilter[] filter: SchemaFilter[]
notify: NotificationAction notify: NotificationAction
} }
@ -65,7 +71,7 @@ export default class TagListItem extends PureComponent<Props, State> {
} }
public render() { public render() {
const {tagKey, db, service, filter} = this.props const {tagKey, db, source, filter, notify} = this.props
const { const {
tagValues, tagValues,
searchTerm, searchTerm,
@ -110,7 +116,8 @@ export default class TagListItem extends PureComponent<Props, State> {
{!this.isLoading && ( {!this.isLoading && (
<TagValueList <TagValueList
db={db} db={db}
service={service} notify={notify}
source={source}
values={tagValues} values={tagValues}
tagKey={tagKey} tagKey={tagKey}
filter={filter} filter={filter}
@ -218,10 +225,10 @@ export default class TagListItem extends PureComponent<Props, State> {
} }
private getTagValues = async () => { private getTagValues = async () => {
const {db, service, tagKey, filter} = this.props const {db, source, tagKey, filter} = this.props
const {searchTerm, limit} = this.state const {searchTerm, limit} = this.state
const response = await fetchTagValues({ const response = await fetchTagValues({
service, source,
db, db,
filter, filter,
tagKey, tagKey,
@ -269,11 +276,11 @@ export default class TagListItem extends PureComponent<Props, State> {
} }
private async getCount() { private async getCount() {
const {service, db, filter, tagKey} = this.props const {source, db, filter, tagKey} = this.props
const {limit, searchTerm} = this.state const {limit, searchTerm} = this.state
try { try {
const response = await fetchTagValues({ const response = await fetchTagValues({
service, source,
db, db,
filter, filter,
tagKey, tagKey,

View File

@ -1,13 +1,16 @@
// Libraries
import React, {PureComponent, MouseEvent} from 'react' import React, {PureComponent, MouseEvent} from 'react'
// Components
import TagValueListItem from 'src/flux/components/TagValueListItem' import TagValueListItem from 'src/flux/components/TagValueListItem'
import LoadingSpinner from 'src/flux/components/LoadingSpinner' import LoadingSpinner from 'src/flux/components/LoadingSpinner'
import {NotificationContext} from 'src/flux/containers/CheckServices'
import {Service, SchemaFilter} from 'src/types' // Types
import {Source, SchemaFilter} from 'src/types'
import {NotificationAction} from 'src/types/notifications'
interface Props { interface Props {
service: Service source: Source
db: string db: string
tagKey: string tagKey: string
values: string[] values: string[]
@ -16,13 +19,15 @@ interface Props {
onLoadMoreValues: () => void onLoadMoreValues: () => void
shouldShowMoreValues: boolean shouldShowMoreValues: boolean
loadMoreCount: number loadMoreCount: number
notify: NotificationAction
} }
export default class TagValueList extends PureComponent<Props> { export default class TagValueList extends PureComponent<Props> {
public render() { public render() {
const { const {
db, db,
service, notify,
source,
values, values,
tagKey, tagKey,
filter, filter,
@ -32,19 +37,15 @@ export default class TagValueList extends PureComponent<Props> {
return ( return (
<> <>
{values.map((v, i) => ( {values.map((v, i) => (
<NotificationContext.Consumer key={v}> <TagValueListItem
{({notify}) => ( key={i}
<TagValueListItem db={db}
key={i} value={v}
db={db} tagKey={tagKey}
value={v} source={source}
tagKey={tagKey} filter={filter}
service={service} notify={notify}
filter={filter} />
notify={notify}
/>
)}
</NotificationContext.Consumer>
))} ))}
{shouldShowMoreValues && ( {shouldShowMoreValues && (
<div className="flux-schema-tree flux-schema--child"> <div className="flux-schema-tree flux-schema--child">

View File

@ -13,7 +13,7 @@ import {
} from 'src/shared/copy/notifications' } from 'src/shared/copy/notifications'
import { import {
Service, Source,
SchemaFilter, SchemaFilter,
RemoteDataState, RemoteDataState,
NotificationAction, NotificationAction,
@ -21,7 +21,7 @@ import {
interface Props { interface Props {
db: string db: string
service: Service source: Source
tagKey: string tagKey: string
value: string value: string
filter: SchemaFilter[] filter: SchemaFilter[]
@ -47,7 +47,7 @@ class TagValueListItem extends PureComponent<Props, State> {
} }
public render() { public render() {
const {db, service, value} = this.props const {db, source, value, notify} = this.props
const {searchTerm, isOpen} = this.state const {searchTerm, isOpen} = this.state
return ( return (
@ -85,7 +85,8 @@ class TagValueListItem extends PureComponent<Props, State> {
)} )}
<TagList <TagList
db={db} db={db}
service={service} notify={notify}
source={source}
tags={this.tags} tags={this.tags}
filter={this.filter} filter={this.filter}
/> />
@ -113,12 +114,12 @@ class TagValueListItem extends PureComponent<Props, State> {
} }
private async getTags() { private async getTags() {
const {db, service} = this.props const {db, source} = this.props
this.setState({loading: RemoteDataState.Loading}) this.setState({loading: RemoteDataState.Loading})
try { try {
const response = await fetchTagKeys(service, db, this.filter) const response = await fetchTagKeys(source, db, this.filter)
const tags = parseValuesColumn(response) const tags = parseValuesColumn(response)
this.setState({tags, loading: RemoteDataState.Done}) this.setState({tags, loading: RemoteDataState.Done})
} catch (error) { } catch (error) {

View File

@ -12,12 +12,12 @@ import {
ScriptStatus, ScriptStatus,
} from 'src/types/flux' } from 'src/types/flux'
import {Service} from 'src/types' import {Source} from 'src/types'
import {ErrorHandling} from 'src/shared/decorators/errors' import {ErrorHandling} from 'src/shared/decorators/errors'
import {HANDLE_VERTICAL, HANDLE_HORIZONTAL} from 'src/shared/constants' import {HANDLE_VERTICAL, HANDLE_HORIZONTAL} from 'src/shared/constants'
interface Props { interface Props {
service: Service source: Source
script: string script: string
body: Body[] body: Body[]
status: ScriptStatus status: ScriptStatus
@ -67,7 +67,6 @@ class TimeMachine extends PureComponent<Props> {
private get builder() { private get builder() {
const { const {
body, body,
service,
suggestions, suggestions,
onAppendFrom, onAppendFrom,
onDeleteBody, onDeleteBody,
@ -82,7 +81,6 @@ class TimeMachine extends PureComponent<Props> {
render: () => ( render: () => (
<BodyBuilder <BodyBuilder
body={body} body={body}
service={service}
suggestions={suggestions} suggestions={suggestions}
onDeleteBody={onDeleteBody} onDeleteBody={onDeleteBody}
onAppendFrom={onAppendFrom} onAppendFrom={onAppendFrom}
@ -96,7 +94,7 @@ class TimeMachine extends PureComponent<Props> {
const { const {
script, script,
status, status,
service, source,
onValidate, onValidate,
suggestions, suggestions,
onChangeScript, onChangeScript,
@ -134,7 +132,7 @@ class TimeMachine extends PureComponent<Props> {
handlePixels: 44, handlePixels: 44,
headerButtons: [], headerButtons: [],
menuOptions: [], menuOptions: [],
render: () => <SchemaExplorer service={service} />, render: () => <SchemaExplorer source={source} />,
headerOrientation: HANDLE_VERTICAL, headerOrientation: HANDLE_VERTICAL,
}, },
] ]

View File

@ -6,11 +6,11 @@ import TimeMachineVis from 'src/flux/components/TimeMachineVis'
import {getTimeSeries} from 'src/flux/apis' import {getTimeSeries} from 'src/flux/apis'
import {getDeep} from 'src/utils/wrappers' import {getDeep} from 'src/utils/wrappers'
import {FluxTable, Service} from 'src/types' import {FluxTable, Source} from 'src/types'
import {Func} from 'src/types/flux' import {Func} from 'src/types/flux'
interface Props { interface Props {
service: Service source: Source
data: FluxTable[] data: FluxTable[]
index: number index: number
bodyID: string bodyID: string
@ -58,8 +58,8 @@ class YieldFuncNode extends PureComponent<Props, State> {
} }
private getData = async (): Promise<void> => { private getData = async (): Promise<void> => {
const {script, service} = this.props const {script, source} = this.props
const results = await getTimeSeries(service, script) const results = await getTimeSeries(source.links.query, script)
const data = getDeep<FluxTable[]>(results, 'tables', []) const data = getDeep<FluxTable[]>(results, 'tables', [])
this.setState({data}) this.setState({data})
} }

View File

@ -1,105 +0,0 @@
import React, {PureComponent, ReactChildren} from 'react'
import {connect} from 'react-redux'
import {WithRouterProps, withRouter} from 'react-router'
import {FluxPage} from 'src/flux'
import EmptyFluxPage from 'src/flux/components/EmptyFluxPage'
import {Source, Service, Notification} from 'src/types'
import {Links} from 'src/types/flux'
import {notify as notifyAction} from 'src/shared/actions/notifications'
import {
updateScript as updateScriptAction,
UpdateScript,
} from 'src/flux/actions'
import * as actions from 'src/shared/actions/services'
export const NotificationContext = React.createContext()
interface Props {
sources: Source[]
services: Service[]
children: ReactChildren
fetchServicesAsync: actions.FetchFluxServicesForSourceAsync
notify: (message: Notification) => void
updateScript: UpdateScript
script: string
links: Links
}
export class CheckServices extends PureComponent<Props & WithRouterProps> {
constructor(props: Props & WithRouterProps) {
super(props)
}
public async componentDidMount() {
const source = this.props.sources.find(
s => s.id === this.props.params.sourceID
)
if (!source) {
return
}
await this.props.fetchServicesAsync(source)
}
public render() {
const {services, notify, updateScript, links, script} = this.props
if (!this.props.services.length) {
return <EmptyFluxPage onGoToNewService={this.handleGoToNewFlux} />
}
return (
<NotificationContext.Provider value={{notify}}>
<FluxPage
source={this.source}
services={services}
links={links}
script={script}
notify={notify}
updateScript={updateScript}
onGoToEditFlux={this.handleGoToEditFlux}
/>
</NotificationContext.Provider>
)
}
private handleGoToNewFlux = () => {
const {router} = this.props
const addFluxResource = `/sources/${this.source.id}/flux/new`
router.push(addFluxResource)
}
private handleGoToEditFlux = (service: Service) => {
const {router} = this.props
const editFluxResource = `/sources/${this.source.id}/flux/${
service.id
}/edit`
router.push(editFluxResource)
}
private get source(): Source {
const {params, sources} = this.props
return sources.find(s => s.id === params.sourceID)
}
}
const mdtp = {
fetchServicesAsync: actions.fetchFluxServicesForSourceAsync,
updateScript: updateScriptAction,
notify: notifyAction,
}
const mstp = ({sources, services, links, script}) => {
return {
links: links.flux,
script,
sources,
services,
}
}
export default withRouter<Props>(connect(mstp, mdtp)(CheckServices))

View File

@ -1,10 +1,11 @@
import React, {PureComponent} from 'react' import React, {PureComponent} from 'react'
import {connect} from 'react-redux'
import _ from 'lodash' import _ from 'lodash'
import TimeMachine from 'src/flux/components/TimeMachine' import TimeMachine from 'src/flux/components/TimeMachine'
import FluxHeader from 'src/flux/components/FluxHeader'
import {ErrorHandling} from 'src/shared/decorators/errors' import {ErrorHandling} from 'src/shared/decorators/errors'
import KeyboardShortcuts from 'src/shared/components/KeyboardShortcuts' import KeyboardShortcuts from 'src/shared/components/KeyboardShortcuts'
import PageHeader from 'src/reusable_ui/components/page_layout/PageHeader'
import { import {
validateSuccess, validateSuccess,
@ -18,7 +19,7 @@ import {getSuggestions, getAST, getTimeSeries} from 'src/flux/apis'
import {builder, argTypes, emptyAST} from 'src/flux/constants' import {builder, argTypes, emptyAST} from 'src/flux/constants'
import {getDeep} from 'src/utils/wrappers' import {getDeep} from 'src/utils/wrappers'
import {Source, Service, Notification, FluxTable} from 'src/types' import {Source, Notification, FluxTable} from 'src/types'
import { import {
Suggestion, Suggestion,
FlatBody, FlatBody,
@ -37,7 +38,6 @@ interface Status {
interface Props { interface Props {
links: Links links: Links
services: Service[]
source: Source source: Source
notify: (message: Notification) => void notify: (message: Notification) => void
script: string script: string
@ -98,18 +98,18 @@ export class FluxPage extends PureComponent<Props, State> {
public render() { public render() {
const {suggestions, body, status} = this.state const {suggestions, body, status} = this.state
const {script} = this.props const {script, source} = this.props
return ( return (
<FluxContext.Provider value={this.getContext}> <FluxContext.Provider value={this.getContext}>
<KeyboardShortcuts onControlEnter={this.getTimeSeries}> <KeyboardShortcuts onControlEnter={this.getTimeSeries}>
<div className="page hosts-list-page"> <div className="page hosts-list-page">
{this.header} <PageHeader titleText="Flux Editor" fullWidth={true} />
<TimeMachine <TimeMachine
body={body} body={body}
script={script} script={script}
status={status} status={status}
service={this.service} source={source}
suggestions={suggestions} suggestions={suggestions}
onValidate={this.handleValidate} onValidate={this.handleValidate}
onAppendFrom={this.handleAppendFrom} onAppendFrom={this.handleAppendFrom}
@ -124,6 +124,7 @@ export class FluxPage extends PureComponent<Props, State> {
) )
} }
<<<<<<< HEAD
private get header(): JSX.Element { private get header(): JSX.Element {
const {services, onGoToEditFlux} = this.props const {services, onGoToEditFlux} = this.props
@ -148,6 +149,8 @@ export class FluxPage extends PureComponent<Props, State> {
return activeService || services[0] return activeService || services[0]
} }
=======
>>>>>>> feature(chronograf): use sources instead of services for flux builder
private get getContext(): Context { private get getContext(): Context {
return { return {
onAddNode: this.handleAddNode, onAddNode: this.handleAddNode,
@ -157,9 +160,9 @@ export class FluxPage extends PureComponent<Props, State> {
onDeleteFuncNode: this.handleDeleteFuncNode, onDeleteFuncNode: this.handleDeleteFuncNode,
onGenerateScript: this.handleGenerateScript, onGenerateScript: this.handleGenerateScript,
onToggleYield: this.handleToggleYield, onToggleYield: this.handleToggleYield,
service: this.service,
data: this.state.data, data: this.state.data,
scriptUpToYield: this.handleScriptUpToYield, scriptUpToYield: this.handleScriptUpToYield,
source: this.props.source,
} }
} }
@ -647,7 +650,7 @@ export class FluxPage extends PureComponent<Props, State> {
} }
private getTimeSeries = async () => { private getTimeSeries = async () => {
const {script, links, notify} = this.props const {script, links, notify, source} = this.props
if (!script) { if (!script) {
return return
@ -661,7 +664,10 @@ export class FluxPage extends PureComponent<Props, State> {
} }
try { try {
const {tables, didTruncate} = await getTimeSeries(this.service, script) const {tables, didTruncate} = await getTimeSeries(
source.links.query,
script
)
this.setState({data: tables}) this.setState({data: tables})
@ -685,4 +691,11 @@ export class FluxPage extends PureComponent<Props, State> {
} }
} }
export default FluxPage const mstp = ({links, script}) => {
return {
links: links.flux,
script,
}
}
export default connect(mstp, null)(FluxPage)

View File

@ -1,5 +1,3 @@
import FluxPage from 'src/flux/containers/FluxPage' import FluxPage from 'src/flux/containers/FluxPage'
import CheckServices from 'src/flux/containers/CheckServices'
import FluxConnectionPage from 'src/flux/containers/FluxConnectionPage'
export {FluxPage, CheckServices, FluxConnectionPage} export {FluxPage}

View File

@ -21,7 +21,7 @@ import {HostsPage, HostPage} from 'src/hosts'
import {DashboardsPage, DashboardPage} from 'src/dashboards' import {DashboardsPage, DashboardPage} from 'src/dashboards'
import {LogsPage} from 'src/logs' import {LogsPage} from 'src/logs'
import {SourcePage, ManageSources} from 'src/sources' import {SourcePage, ManageSources} from 'src/sources'
import {CheckServices, FluxConnectionPage} from 'src/flux' import {FluxPage} from 'src/flux'
import NotFound from 'src/shared/components/NotFound' import NotFound from 'src/shared/components/NotFound'
import {getLinksAsync} from 'src/shared/actions/links' import {getLinksAsync} from 'src/shared/actions/links'
@ -114,7 +114,7 @@ class Root extends PureComponent<{}, State> {
<Route path="manage-sources" component={ManageSources} /> <Route path="manage-sources" component={ManageSources} />
<Route path="manage-sources/new" component={SourcePage} /> <Route path="manage-sources/new" component={SourcePage} />
<Route path="manage-sources/:id/edit" component={SourcePage} /> <Route path="manage-sources/:id/edit" component={SourcePage} />
<Route path="delorean" component={CheckServices} /> <Route path="delorean" component={FluxPage} />
</Route> </Route>
</Route> </Route>
<Route path="*" component={NotFound} /> <Route path="*" component={NotFound} />

View File

@ -1,10 +1,10 @@
import _ from 'lodash' import _ from 'lodash'
import AJAX from 'src/utils/ajax' import AJAX from 'src/utils/ajax'
import {Service, SchemaFilter} from 'src/types' import {Source, SchemaFilter} from 'src/types'
export const measurements = async ( export const measurements = async (
service: Service, source: Source,
db: string db: string
): Promise<any> => { ): Promise<any> => {
const script = ` const script = `
@ -15,11 +15,11 @@ export const measurements = async (
|> group() |> group()
` `
return proxy(service, script) return metaQuery(source, script)
} }
export const tagKeys = async ( export const tagKeys = async (
service: Service, source: Source,
db: string, db: string,
filter: SchemaFilter[] filter: SchemaFilter[]
): Promise<any> => { ): Promise<any> => {
@ -41,11 +41,11 @@ export const tagKeys = async (
${tagKeyFilter} ${tagKeyFilter}
` `
return proxy(service, script) return metaQuery(source, script)
} }
interface TagValuesParams { interface TagValuesParams {
service: Service source: Source
db: string db: string
tagKey: string tagKey: string
limit: number limit: number
@ -56,7 +56,7 @@ interface TagValuesParams {
export const tagValues = async ({ export const tagValues = async ({
db, db,
service, source,
tagKey, tagKey,
limit, limit,
filter = [], filter = [],
@ -84,11 +84,11 @@ export const tagValues = async ({
${countFunc} ${countFunc}
` `
return proxy(service, script) return metaQuery(source, script)
} }
export const tagsFromMeasurement = async ( export const tagsFromMeasurement = async (
service: Service, source: Source,
db: string, db: string,
measurement: string measurement: string
): Promise<any> => { ): Promise<any> => {
@ -100,7 +100,7 @@ export const tagsFromMeasurement = async (
|> keys(except:["_time","_value","_start","_stop"]) |> keys(except:["_time","_value","_start","_stop"])
` `
return proxy(service, script) return metaQuery(source, script)
} }
const tagsetFilter = (filter: SchemaFilter[]): string => { const tagsetFilter = (filter: SchemaFilter[]): string => {
@ -113,17 +113,15 @@ const tagsetFilter = (filter: SchemaFilter[]): string => {
return `|> filter(fn: (r) => ${predicates.join(' and ')} )` return `|> filter(fn: (r) => ${predicates.join(' and ')} )`
} }
const proxy = async (service: Service, script: string) => { const metaQuery = async (source: Source, script: string) => {
const and = encodeURIComponent('&') const url = source.links.query
const mark = encodeURIComponent('?')
const garbage = script.replace(/\s/g, '') // server cannot handle whitespace
try { try {
const response = await AJAX({ const response = await AJAX({
method: 'POST', method: 'POST',
url: `${ url,
service.links.proxy data: {
}?path=/v1/query${mark}orgName=defaulorgname${and}q=${garbage}`, script,
},
}) })
return response.data return response.data

View File

@ -1,5 +1,5 @@
import {Service} from 'src/types'
// function definitions // function definitions
import {Source} from 'src/types'
export type OnDeleteFuncNode = (ids: DeleteFuncNodeArgs) => void export type OnDeleteFuncNode = (ids: DeleteFuncNodeArgs) => void
export type OnChangeArg = (inputArg: InputArg) => void export type OnChangeArg = (inputArg: InputArg) => void
export type OnAddNode = ( export type OnAddNode = (
@ -29,6 +29,7 @@ export interface ScriptStatus {
} }
export interface Context { export interface Context {
source: Source
onAddNode: OnAddNode onAddNode: OnAddNode
onChangeArg: OnChangeArg onChangeArg: OnChangeArg
onSubmitScript: OnSubmitScript onSubmitScript: OnSubmitScript
@ -36,7 +37,6 @@ export interface Context {
onDeleteFuncNode: OnDeleteFuncNode onDeleteFuncNode: OnDeleteFuncNode
onGenerateScript: OnGenerateScript onGenerateScript: OnGenerateScript
onToggleYield: OnToggleYield onToggleYield: OnToggleYield
service: Service
data: FluxTable[] data: FluxTable[]
scriptUpToYield: ScriptUpToYield scriptUpToYield: ScriptUpToYield
} }

View File

@ -29,6 +29,7 @@ export interface Source {
} }
export interface SourceLinks { export interface SourceLinks {
query: string
self: string self: string
kapacitors: string kapacitors: string
proxy: string proxy: string

View File

@ -23,6 +23,7 @@ import {LineColor, ColorNumber} from 'src/types/colors'
import {ServerLogConfig, ServerColumn} from 'src/types/logs' import {ServerLogConfig, ServerColumn} from 'src/types/logs'
export const sourceLinks: SourceLinks = { export const sourceLinks: SourceLinks = {
query: '/chronograf/v1/query/4',
services: '/chronograf/v1/sources/4', services: '/chronograf/v1/sources/4',
self: '/chronograf/v1/sources/4', self: '/chronograf/v1/sources/4',
kapacitors: '/chronograf/v1/sources/4/kapacitors', kapacitors: '/chronograf/v1/sources/4/kapacitors',

View File

@ -1,7 +1,7 @@
import React from 'react' import React from 'react'
import {shallow} from 'enzyme' import {shallow} from 'enzyme'
import FromDatabaseDropdown from 'src/flux/components/FromDatabaseDropdown' import FromDatabaseDropdown from 'src/flux/components/FromDatabaseDropdown'
import {service} from 'test/resources' import {source} from 'test/resources'
jest.mock('src/shared/apis/metaQuery', () => require('mocks/flux/apis')) jest.mock('src/shared/apis/metaQuery', () => require('mocks/flux/apis'))
@ -12,7 +12,7 @@ const setup = () => {
value: 'db1', value: 'db1',
bodyID: '2', bodyID: '2',
declarationID: '1', declarationID: '1',
service, source,
onChangeArg: () => {}, onChangeArg: () => {},
} }

View File

@ -1,7 +1,7 @@
import React from 'react' import React from 'react'
import {shallow} from 'enzyme' import {shallow} from 'enzyme'
import FuncArg from 'src/flux/components/FuncArg' import FuncArg from 'src/flux/components/FuncArg'
import {service} from 'test/resources' import {source} from 'test/resources'
const setup = () => { const setup = () => {
const props = { const props = {
@ -13,7 +13,7 @@ const setup = () => {
args: [], args: [],
value: '', value: '',
type: '', type: '',
service, source,
onChangeArg: () => {}, onChangeArg: () => {},
onGenerateScript: () => {}, onGenerateScript: () => {},
} }

View File

@ -1,14 +1,14 @@
import React from 'react' import React from 'react'
import {shallow} from 'enzyme' import {shallow} from 'enzyme'
import TimeMachine from 'src/flux/components/TimeMachine' import TimeMachine from 'src/flux/components/TimeMachine'
import {service} from 'test/resources' import {source} from 'test/resources'
const setup = () => { const setup = () => {
const props = { const props = {
script: '', script: '',
body: [], body: [],
data: [], data: [],
service, source,
suggestions: [], suggestions: [],
onSubmitScript: () => {}, onSubmitScript: () => {},
onChangeScript: () => {}, onChangeScript: () => {},

View File

@ -30,6 +30,7 @@ export const me = {
} }
export const sourceLinks: SourceLinks = { export const sourceLinks: SourceLinks = {
query: '/chronograf/v1/sources/16/query',
services: '/chronograf/v1/sources/16/services', services: '/chronograf/v1/sources/16/services',
self: '/chronograf/v1/sources/16', self: '/chronograf/v1/sources/16',
kapacitors: '/chronograf/v1/sources/16/kapacitors', kapacitors: '/chronograf/v1/sources/16/kapacitors',