commit
789d3d7f1e
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
) : (
|
||||
|
|
|
@ -41,6 +41,8 @@ class FluxHeader extends PureComponent<Props> {
|
|||
services={services}
|
||||
service={service}
|
||||
allowInfluxQL={false}
|
||||
allowFlux={true}
|
||||
allowDynamicSource={false}
|
||||
onChangeService={onChangeService}
|
||||
/>
|
||||
<button
|
||||
|
|
|
@ -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}`
|
||||
|
|
|
@ -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 = () => {
|
||||
|
|
|
@ -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>
|
||||
)
|
||||
|
|
|
@ -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',
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue