Convert VisHeader to ts

pull/3431/head
Andrew Watkins 2018-05-11 19:41:30 -07:00
parent 657dc2970b
commit 6554cf0f35
8 changed files with 176 additions and 80 deletions

View File

@ -1,5 +1,13 @@
import AJAX from 'src/utils/ajax'
import {Source} from 'src/types'
import _ from 'lodash'
import moment from 'moment'
import download from 'src/external/download'
import {proxy} from 'src/utils/queryUrlGenerator'
import {timeSeriesToTableGraph} from 'src/utils/timeSeriesTransformers'
import {dataToCSV} from 'src/shared/parsing/dataToCSV'
import {TEMPLATES} from 'src/shared/constants'
import {Source, QueryConfig} from 'src/types'
export const writeLineProtocol = async (
source: Source,
@ -11,3 +19,49 @@ export const writeLineProtocol = async (
method: 'POST',
data,
})
interface DeprecatedQuery {
id: string
host: string
queryConfig: QueryConfig
text: string
}
export const getDataForCSV = (
query: DeprecatedQuery,
errorThrown
) => async () => {
try {
const response = await fetchTimeSeriesForCSV({
source: query.host,
query: query.text,
tempVars: TEMPLATES,
})
const {data} = timeSeriesToTableGraph([{response}])
const name = csvName(query.queryConfig)
download(dataToCSV(data), `${name}.csv`, 'text/plain')
} catch (error) {
errorThrown(error, 'Unable to download .csv file')
console.error(error)
}
}
const fetchTimeSeriesForCSV = async ({source, query, tempVars}) => {
try {
const {data} = await proxy({source, query, tempVars})
return data
} catch (error) {
console.error(error)
throw error
}
}
const csvName = (query: QueryConfig): string => {
const db = _.get(query, 'database', '')
const rp = _.get(query, 'retentionPolicy', '')
const measurement = _.get(query, 'measurement', '')
const timestring = moment().format('YYYY-MM-DD-HH-mm')
return `${db}.${rp}.${measurement}.${timestring}`
}

View File

@ -1,72 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import classnames from 'classnames'
import _ from 'lodash'
import moment from 'moment'
import {fetchTimeSeriesAsync} from 'shared/actions/timeSeries'
import {timeSeriesToTableGraph} from 'src/utils/timeSeriesTransformers'
import {dataToCSV} from 'src/shared/parsing/dataToCSV'
import download from 'src/external/download.js'
import {TEMPLATES} from 'src/shared/constants'
const getDataForCSV = (query, errorThrown) => async () => {
try {
const response = await fetchTimeSeriesAsync({
source: query.host,
query,
tempVars: TEMPLATES,
})
const {data} = timeSeriesToTableGraph([{response}])
const db = _.get(query, ['queryConfig', 'database'], '')
const rp = _.get(query, ['queryConfig', 'retentionPolicy'], '')
const measurement = _.get(query, ['queryConfig', 'measurement'], '')
const timestring = moment().format('YYYY-MM-DD-HH-mm')
const name = `${db}.${rp}.${measurement}.${timestring}`
download(dataToCSV(data), `${name}.csv`, 'text/plain')
} catch (error) {
errorThrown(error, 'Unable to download .csv file')
console.error(error)
}
}
const VisHeader = ({views, view, onToggleView, query, errorThrown}) => (
<div className="graph-heading">
{views.length ? (
<ul className="nav nav-tablist nav-tablist-sm">
{views.map(v => (
<li
key={v}
onClick={onToggleView(v)}
className={classnames({active: view === v})}
data-test={`data-${v}`}
>
{_.upperFirst(v)}
</li>
))}
</ul>
) : null}
{query ? (
<div
className="btn btn-sm btn-default dlcsv"
onClick={getDataForCSV(query, errorThrown)}
>
<span className="icon download dlcsv" />
.csv
</div>
) : null}
</div>
)
const {arrayOf, func, shape, string} = PropTypes
VisHeader.propTypes = {
views: arrayOf(string).isRequired,
view: string.isRequired,
onToggleView: func.isRequired,
query: shape(),
errorThrown: func.isRequired,
}
export default VisHeader

View File

@ -0,0 +1,42 @@
import React, {PureComponent} from 'react'
import {getDataForCSV} from 'src/data_explorer/apis'
import VisHeaderTabs from 'src/data_explorer/components/VisHeaderTabs'
import {OnToggleView} from 'src/data_explorer/components/VisHeaderTab'
interface Props {
views: string[]
view: string
query: any
onToggleView: OnToggleView
errorThrown: () => void
}
class VisHeader extends PureComponent<Props> {
public render() {
const {views, view, onToggleView, query, errorThrown} = this.props
return (
<div className="graph-heading">
{!!views.length && (
<VisHeaderTabs
view={view}
views={views}
currentView={view}
onToggleView={onToggleView}
/>
)}
{query && (
<div
className="btn btn-sm btn-default dlcsv"
onClick={getDataForCSV(query, errorThrown)}
>
<span className="icon download dlcsv" />
.csv
</div>
)}
</div>
)
}
}
export default VisHeader

View File

@ -0,0 +1,36 @@
import React, {PureComponent} from 'react'
import classnames from 'classnames'
import _ from 'lodash'
export type OnToggleView = (view: string) => void
interface TabProps {
view: string
currentView: string
onToggleView: OnToggleView
}
class VisHeaderTab extends PureComponent<TabProps> {
public render() {
return (
<li className={this.className} onClick={this.handleClick}>
{this.text}
</li>
)
}
private get className(): string {
const {view, currentView} = this.props
return classnames({active: view === currentView})
}
private handleClick = () => {
this.props.onToggleView(this.props.view)
}
private get text(): string {
return _.upperFirst(this.props.view)
}
}
export default VisHeaderTab

View File

@ -0,0 +1,28 @@
import React, {SFC} from 'react'
import VisHeaderTab, {
OnToggleView,
} from 'src/data_explorer/components/VisHeaderTab'
interface Props {
views: string[]
view: string
currentView: string
onToggleView: OnToggleView
}
const VisHeaderTabs: SFC<Props> = ({views, currentView, onToggleView}) => {
return (
<ul className="nav nav-tablist nav-tablist-sm">
{views.map(v => (
<VisHeaderTab
key={v}
view={v}
currentView={currentView}
onToggleView={onToggleView}
/>
))}
</ul>
)
}
export default VisHeaderTabs

View File

@ -113,11 +113,11 @@ class DataExplorerVisualization extends PureComponent<Props, State> {
return activeQuery || defaultQuery
}
private handleToggleView = view => () => {
private handleToggleView = (view: string): void => {
this.setState({view})
}
private getQueryText(queryConfigs, index) {
private getQueryText(queryConfigs, index): string {
// rawText can be null
return _.get(queryConfigs, [`${index}`, 'rawText'], '') || ''
}

View File

@ -5,7 +5,9 @@ import _ from 'lodash'
import {errorThrown} from 'shared/actions/errors'
export const handleLoading = (query, editQueryStatus) => {
editQueryStatus(query.id, {loading: true})
editQueryStatus(query.id, {
loading: true,
})
}
// {results: [{}]}
export const handleSuccess = (data, query, editQueryStatus) => {
@ -22,12 +24,16 @@ export const handleSuccess = (data, query, editQueryStatus) => {
// 200 from chrono server but influx returns an "error" = warning
if (error) {
editQueryStatus(query.id, {warn: error})
editQueryStatus(query.id, {
warn: error,
})
return data
}
// 200 from server and results contains data = success
editQueryStatus(query.id, {success: 'Success!'})
editQueryStatus(query.id, {
success: 'Success!',
})
return data
}
@ -39,7 +45,9 @@ export const handleError = (error, query, editQueryStatus) => {
)
// 400 from chrono server = fail
editQueryStatus(query.id, {error: message})
editQueryStatus(query.id, {
error: message,
})
}
export const fetchTimeSeriesAsync = async (

View File

@ -3,7 +3,7 @@ import AJAX from 'src/utils/ajax'
interface ProxyQuery {
source: string
query: string
db: string
db?: string
rp?: string
tempVars?: string
resolution?: string