Merge pull request #4254 from influxdata/flux/dynamic-sources

Flux/dynamic sources
pull/4269/head
Iris Scholten 2018-08-20 21:30:24 -07:00 committed by GitHub
commit 789d3d7f1e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 164 additions and 55 deletions

View File

@ -5,6 +5,7 @@
1. [#4220](https://github.com/influxdata/chronograf/pull/4220): Add ability to copy expanded/untruncated log message
1. [#4228](https://github.com/influxdata/chronograf/pull/4228): Add close button for logs pop over
1. [#4241](https://github.com/influxdata/chronograf/pull/4241): Add search attributes to log viewer
1. [#4254](https://github.com/influxdata/chronograf/pull/4254): Add Dynamic Source option to CEO source selector
### UI Improvements
1. [#4227](https://github.com/influxdata/chronograf/pull/4227): Redesign Cell Editor Overlay for reuse in other parts of application

View File

@ -1,7 +1,10 @@
// Libraries
import React, {SFC} from 'react'
// Componentes
import SourceDropdown from 'src/flux/components/SourceDropdown'
// Types
import * as QueriesModels from 'src/types/queries'
import * as SourcesModels from 'src/types/sources'
import {Service} from 'src/types'
@ -12,6 +15,8 @@ interface Props {
service: Service
services: Service[]
queries: QueriesModels.QueryConfig[]
isDynamicSourceSelected: boolean
onSelectDynamicSource: () => void
onChangeService: (service: Service, source: SourcesModels.Source) => void
}
@ -22,6 +27,8 @@ const SourceSelector: SFC<Props> = ({
services,
queries,
onChangeService,
isDynamicSourceSelected,
onSelectDynamicSource,
}) => {
return sources.length > 1 && queries.length ? (
<div className="source-selector">
@ -32,7 +39,12 @@ const SourceSelector: SFC<Props> = ({
source={source}
sources={sources}
allowInfluxQL={true}
// TODO: when flux is added into CEO/DE, change to true
allowFlux={false}
allowDynamicSource={true}
isDynamicSourceSelected={isDynamicSourceSelected}
onChangeService={onChangeService}
onSelectDynamicSource={onSelectDynamicSource}
/>
</div>
) : (

View File

@ -41,6 +41,8 @@ class FluxHeader extends PureComponent<Props> {
services={services}
service={service}
allowInfluxQL={false}
allowFlux={true}
allowDynamicSource={false}
onChangeService={onChangeService}
/>
<button

View File

@ -1,7 +1,13 @@
// Libraries
import React, {PureComponent} from 'react'
// Components
import Dropdown from 'src/reusable_ui/components/dropdowns/Dropdown'
// Constants
import {DynamicSource} from 'src/sources/constants'
// types
import {Service, Source, ServiceLinks, SourceLinks} from 'src/types'
interface Props {
@ -10,6 +16,10 @@ interface Props {
services: Service[]
sources: Source[]
allowInfluxQL: boolean
allowFlux: boolean
allowDynamicSource: boolean
isDynamicSourceSelected?: boolean
onSelectDynamicSource?: () => void
onChangeService: (service: Service, source: Source) => void
}
@ -32,8 +42,18 @@ class SourceDropdown extends PureComponent<Props> {
)
}
private handleSelect = (choice: SourceDropdownItem) => {
const {sources, services} = this.props
private handleSelect = (choice: SourceDropdownItem): void => {
const {
sources,
services,
onChangeService,
onSelectDynamicSource,
} = this.props
if (choice.sourceID === DynamicSource.id && onSelectDynamicSource) {
onSelectDynamicSource()
return
}
const source = sources.find(src => {
return src.id === choice.sourceID
@ -42,57 +62,95 @@ class SourceDropdown extends PureComponent<Props> {
return s.id === choice.serviceID
})
this.props.onChangeService(service, source)
onChangeService(service, source)
}
private get dropdownItems(): JSX.Element[] {
const {services, sources, allowInfluxQL} = this.props
const {sources, allowFlux, allowInfluxQL, allowDynamicSource} = this.props
return sources.reduce((acc, source) => {
const servicesForSource = services.filter(service => {
return service.sourceID === source.id
})
const serviceItems = servicesForSource.map(service => {
const serviceDropdownItem: SourceDropdownItem = {
sourceID: source.id,
serviceID: service.id,
links: service.links,
}
return (
<Dropdown.Item
key={`${source.id}-${service.id}`}
id={`${source.id}-${service.id}`}
value={serviceDropdownItem}
>
{`${source.name} / ${service.name} (flux)`}
</Dropdown.Item>
)
})
const sourceOptions = sources.reduce((acc, source) => {
let items = []
if (allowFlux) {
items = [...items, ...this.fluxSourceItems(source)]
}
if (allowInfluxQL) {
const sourceDropdownItem: SourceDropdownItem = {
sourceID: source.id,
links: source.links,
}
const influxQLDropdownItem = (
<Dropdown.Item
key={source.id}
id={source.id}
value={sourceDropdownItem}
>
{`${source.name} (InfluxQL)`}
</Dropdown.Item>
)
return [...acc, ...serviceItems, influxQLDropdownItem]
items = [...items, this.influxQLSourceItem(source)]
}
return [...acc, ...serviceItems]
return [...acc, ...items]
}, [])
if (allowDynamicSource) {
return [...sourceOptions, this.dynamicSourceOption]
}
return sourceOptions
}
private get dynamicSourceOption(): JSX.Element {
const dynamicSourceDropdownItem = {
sourceID: DynamicSource.id,
}
return (
<Dropdown.Item
key={DynamicSource.id}
id={DynamicSource.id}
value={dynamicSourceDropdownItem}
>
{DynamicSource.name}
</Dropdown.Item>
)
}
private influxQLSourceItem(source: Source): JSX.Element {
const sourceDropdownItem: SourceDropdownItem = {
sourceID: source.id,
links: source.links,
}
return (
<Dropdown.Item key={source.id} id={source.id} value={sourceDropdownItem}>
{`${source.name} (InfluxQL)`}
</Dropdown.Item>
)
}
private fluxSourceItems(source: Source): JSX.Element[] {
const {services} = this.props
const servicesForSource = services.filter(service => {
return service.sourceID === source.id
})
return servicesForSource.map(service => {
const serviceDropdownItem: SourceDropdownItem = {
sourceID: source.id,
serviceID: service.id,
links: service.links,
}
return (
<Dropdown.Item
key={`${source.id}-${service.id}`}
id={`${source.id}-${service.id}`}
value={serviceDropdownItem}
>
{`${source.name} / ${service.name} (flux)`}
</Dropdown.Item>
)
})
}
private get selectedID(): string {
const {service, source} = this.props
const {
service,
source,
allowDynamicSource,
isDynamicSourceSelected,
} = this.props
if (allowDynamicSource && isDynamicSourceSelected) {
return DynamicSource.id
}
if (service) {
return `${service.sourceID}-${service.id}`

View File

@ -66,22 +66,29 @@ interface State {
activeEditorTab: CEOTabs
selectedSource: Source
selectedService: Service
useDynamicSource: boolean
}
class TimeMachine extends PureComponent<Props, State> {
constructor(props: Props) {
super(props)
const {queryDrafts} = props
const useDynamicSource = getDeep(queryDrafts, '0.source', '') === ''
this.state = {
activeQueryIndex: 0,
activeEditorTab: CEOTabs.Queries,
selectedService: null,
selectedSource: null,
useDynamicSource,
}
}
public render() {
const {services} = this.props
const {useDynamicSource} = this.state
const horizontalDivisions = [
{
name: '',
@ -112,6 +119,8 @@ class TimeMachine extends PureComponent<Props, State> {
service={this.service}
services={services}
onChangeService={this.handleChangeService}
onSelectDynamicSource={this.handleSelectDynamicSource}
isDynamicSourceSelected={useDynamicSource}
/>
<div className="deceo--container">
<Threesizer
@ -206,22 +215,25 @@ class TimeMachine extends PureComponent<Props, State> {
private get source(): Source {
const {source, sources, queryDrafts} = this.props
const {selectedSource} = this.state
const {selectedSource, useDynamicSource} = this.state
if (selectedSource) {
return selectedSource
}
const query = _.get(queryDrafts, 0)
const querySource = _.get(query, 'source')
if (!query || !querySource) {
// return current source
if (useDynamicSource) {
return source
}
const foundSource = sources.find(
s => s.links.self === _.get(query, 'source', null)
)
const queryDraft = _.get(queryDrafts, 0)
const querySource = _.get(queryDraft, 'source')
if (!queryDraft || !querySource) {
return source
}
const foundSource = sources.find(s => s.links.self === querySource)
if (foundSource) {
return foundSource
}
@ -356,10 +368,7 @@ class TimeMachine extends PureComponent<Props, State> {
}
}
private handleChangeService = (
selectedService: Service,
selectedSource: Source
) => {
private updateQueryDrafts(selectedSource: Source) {
const {queryDrafts, updateQueryDrafts} = this.props
const queries: CellQuery[] = queryDrafts.map(q => {
@ -372,7 +381,23 @@ class TimeMachine extends PureComponent<Props, State> {
})
updateQueryDrafts(queries)
this.setState({selectedService, selectedSource})
}
private handleChangeService = (
selectedService: Service,
selectedSource: Source
): void => {
const useDynamicSource = false
this.updateQueryDrafts(selectedSource)
this.setState({selectedService, selectedSource, useDynamicSource})
}
private handleSelectDynamicSource = (): void => {
const useDynamicSource = true
this.updateQueryDrafts(null)
this.setState({useDynamicSource})
}
private handleAddQuery = () => {

View File

@ -11,8 +11,10 @@ interface Props {
sources: SourcesModels.SourceOption[]
service: Service
services: Service[]
isDynamicSourceSelected: boolean
onChangeService: (service: Service, source: SourcesModels.Source) => void
queries: QueriesModels.QueryConfig[]
onSelectDynamicSource: () => void
}
const TimeMachineControls: SFC<Props> = ({
@ -22,6 +24,8 @@ const TimeMachineControls: SFC<Props> = ({
queries,
services,
onChangeService,
isDynamicSourceSelected,
onSelectDynamicSource,
}) => {
return (
<div className="deceo--controls">
@ -32,6 +36,8 @@ const TimeMachineControls: SFC<Props> = ({
services={services}
queries={queries}
onChangeService={onChangeService}
isDynamicSourceSelected={isDynamicSourceSelected}
onSelectDynamicSource={onSelectDynamicSource}
/>
</div>
)

View File

@ -3,3 +3,8 @@ export const REQUIRED_ROLE_COPY =
export const KAPACITOR_TOOLTIP_COPY =
'<p>Kapacitor Connections are<br/>scoped per InfluxDB Connection.<br/>Only one can be active at a time.</p>'
export enum DynamicSource {
name = 'Dynamic Source',
id = 'dynamic',
}