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 (
service: Service,
url: string, // query URI
script: string
): 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 responseByteLength: number
@ -69,7 +62,11 @@ export const getTimeSeries = async (
// 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
// 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)
responseBody = body

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -3,11 +3,10 @@ import _ from 'lodash'
import FilterTagValueListItem from 'src/flux/components/FilterTagValueListItem'
import LoadingSpinner from 'src/flux/components/LoadingSpinner'
import {Service, SchemaFilter} from 'src/types'
import {SchemaFilter} from 'src/types'
import {SetFilterTagValue} from 'src/types/flux'
interface Props {
service: Service
db: string
tagKey: 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 {OnChangeArg} from 'src/types/flux'
import {Service} from 'src/types'
import {Source} from 'src/types'
interface Props {
funcID: string
@ -14,7 +15,7 @@ interface Props {
bodyID: string
declarationID: string
onChangeArg: OnChangeArg
service: Service
source: Source
}
interface State {
@ -34,10 +35,11 @@ class FromDatabaseDropdown extends PureComponent<Props, State> {
}
public async componentDidMount() {
const {service} = this.props
const {source} = this.props
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 sorted = databases.sort()

View File

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

View File

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

View File

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

View File

@ -1,24 +1,39 @@
// Libraries
import React, {PureComponent} from 'react'
import {connect} from 'react-redux'
// Components
import DatabaseList from 'src/flux/components/DatabaseList'
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 {
service: Service
source: Source
notify: NotificationAction
}
class SchemaExplorer extends PureComponent<Props> {
public render() {
const {service} = this.props
const {source, notify} = this.props
return (
<div className="flux-schema-explorer">
<FancyScrollbar>
<DatabaseList service={service} />
<DatabaseList source={source} notify={notify} />
</FancyScrollbar>
</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 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 {
db: string
service: Service
source: Source
tags: string[]
filter: SchemaFilter[]
notify: NotificationAction
}
export default class TagList extends PureComponent<Props> {
public render() {
const {db, service, tags, filter} = this.props
const {db, source, tags, filter, notify} = this.props
if (tags.length) {
return (
<>
{tags.map(t => (
<NotificationContext.Consumer key={t}>
{({notify}) => (
<TagListItem
db={db}
tagKey={t}
service={service}
filter={filter}
notify={notify}
/>
)}
</NotificationContext.Consumer>
<TagListItem
key={t}
db={db}
tagKey={t}
source={source}
filter={filter}
notify={notify}
/>
))}
</>
)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,7 +1,7 @@
import React from 'react'
import {shallow} from 'enzyme'
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'))
@ -12,7 +12,7 @@ const setup = () => {
value: 'db1',
bodyID: '2',
declarationID: '1',
service,
source,
onChangeArg: () => {},
}

View File

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

View File

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

View File

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