Convert files to Typescript and fix errors

Co-authored-by: Brandon Farmer <bthesorceror@gmail.com>
pull/10616/head
Iris Scholten 2018-04-30 17:37:40 -07:00
parent 39278205d7
commit f8940863f4
11 changed files with 258 additions and 200 deletions

View File

@ -3,6 +3,11 @@ import React, {Component} from 'react'
import _ from 'lodash' import _ from 'lodash'
import uuid from 'uuid' import uuid from 'uuid'
import {
CellEditorOverlayActions,
CellEditorOverlayActionsFunc,
} from 'src/types/dashboard'
import ResizeContainer from 'src/shared/components/ResizeContainer' import ResizeContainer from 'src/shared/components/ResizeContainer'
import QueryMaker from 'src/dashboards/components/QueryMaker' import QueryMaker from 'src/dashboards/components/QueryMaker'
import Visualization from 'src/dashboards/components/Visualization' import Visualization from 'src/dashboards/components/Visualization'
@ -243,7 +248,10 @@ class CellEditorOverlay extends Component<Props, State> {
this.overlayRef = r this.overlayRef = r
} }
private queryStateReducer = queryModifier => (queryID, ...payload) => { private queryStateReducer = (queryModifier): CellEditorOverlayActionsFunc => (
queryID: string,
...payload: any[]
) => {
const {queriesWorkingDraft} = this.state const {queriesWorkingDraft} = this.state
const query = queriesWorkingDraft.find(q => q.id === queryID) const query = queriesWorkingDraft.find(q => q.id === queryID)
@ -455,11 +463,26 @@ class CellEditorOverlay extends Component<Props, State> {
) )
} }
private get queryActions() { private get queryActions(): CellEditorOverlayActions {
return { const original = {
editRawTextAsync: this.handleEditRawText, editRawTextAsync: () => Promise.resolve(),
..._.mapValues(queryModifiers, this.queryStateReducer), ...queryModifiers,
} }
const mapped = _.reduce<CellEditorOverlayActions, CellEditorOverlayActions>(
original,
(acc, v, k) => {
acc[k] = this.queryStateReducer(v)
return acc
},
original
)
const result = {
...mapped,
editRawTextAsync: this.handleEditRawText,
}
return result
} }
private get sourceLink(): string { private get sourceLink(): string {

View File

@ -29,8 +29,8 @@ interface Props {
queries: QueryConfig[] queries: QueryConfig[]
timeRange: TimeRange timeRange: TimeRange
actions: CellEditorOverlayActions actions: CellEditorOverlayActions
setActiveQueryIndex: () => void setActiveQueryIndex: (index: number) => void
onDeleteQuery: () => void onDeleteQuery: (index: number) => void
activeQueryIndex: number activeQueryIndex: number
activeQuery: QueryConfig activeQuery: QueryConfig
onAddQuery: () => void onAddQuery: () => void
@ -76,7 +76,6 @@ const QueryMaker: SFC<Props> = ({
source={source} source={source}
actions={actions} actions={actions}
query={activeQuery} query={activeQuery}
onAddQuery={onAddQuery}
initialGroupByTime={initialGroupByTime} initialGroupByTime={initialGroupByTime}
isQuerySupportedByExplorer={_.get( isQuerySupportedByExplorer={_.get(
activeQuery, activeQuery,

View File

@ -7,6 +7,7 @@ import groupByTimeOptions from 'src/data_explorer/data/groupByTimes'
import Dropdown from 'src/shared/components/Dropdown' import Dropdown from 'src/shared/components/Dropdown'
import {AUTO_GROUP_BY} from 'src/shared/constants' import {AUTO_GROUP_BY} from 'src/shared/constants'
import {GroupBy} from 'src/types'
interface GroupByTimeOption { interface GroupByTimeOption {
defaultTimeBound: string defaultTimeBound: string
@ -17,7 +18,7 @@ interface GroupByTimeOption {
interface Props { interface Props {
location?: Location location?: Location
selected: string selected: string
onChooseGroupByTime: () => void onChooseGroupByTime: (groupBy: GroupBy) => void
isDisabled: boolean isDisabled: boolean
} }

View File

@ -1,7 +1,8 @@
import React, {PureComponent} from 'react' import React, {PureComponent} from 'react'
import PropTypes from 'prop-types'
import _ from 'lodash' import _ from 'lodash'
import {QueryConfig, GroupBy, Source, TimeShift} from 'src/types'
import QueryOptions from 'src/shared/components/QueryOptions' import QueryOptions from 'src/shared/components/QueryOptions'
import FieldListItem from 'src/data_explorer/components/FieldListItem' import FieldListItem from 'src/data_explorer/components/FieldListItem'
import FancyScrollbar from 'src/shared/components/FancyScrollbar' import FancyScrollbar from 'src/shared/components/FancyScrollbar'
@ -16,8 +17,67 @@ import {
} from 'src/shared/reducers/helpers/fields' } from 'src/shared/reducers/helpers/fields'
import {ErrorHandling} from 'src/shared/decorators/errors' import {ErrorHandling} from 'src/shared/decorators/errors'
interface GroupByOption extends GroupBy {
menuOption: string
}
interface TimeShiftOption extends TimeShift {
text: string
}
interface Links {
proxy: string
}
interface Field {
type: string
value: string
}
interface FieldFunc extends Field {
args: FuncArg[]
}
interface FuncArg {
value: string
type: string
}
interface ApplyFuncsToFieldArgs {
field: Field
funcs: FuncArg[]
}
interface Props {
query: QueryConfig
onTimeShift: (shift: TimeShiftOption) => void
onToggleField: (field: Field) => void
onGroupByTime: (groupByOption: string) => void
onFill: (fill: string) => void
applyFuncsToField: (field: ApplyFuncsToFieldArgs, groupBy: GroupBy) => void
isKapacitorRule: boolean
querySource: {
links: Links
}
removeFuncs: (fields: Field[]) => void
addInitialField: (field: Field, groupBy: GroupBy) => void
initialGroupByTime: string | null
isQuerySupportedByExplorer: boolean
}
interface State {
fields: Field[]
}
interface Context {
source: Source
}
@ErrorHandling @ErrorHandling
class FieldList extends PureComponent { class FieldList extends PureComponent<Props, State> {
public static context: Context
public static defaultProps: Partial<Props> = {
isKapacitorRule: false,
initialGroupByTime: null,
}
constructor(props) { constructor(props) {
super(props) super(props)
this.state = { this.state = {
@ -31,7 +91,7 @@ class FieldList extends PureComponent {
return return
} }
this._getFields() this.getFields()
} }
public componentDidUpdate(prevProps) { public componentDidUpdate(prevProps) {
@ -55,91 +115,7 @@ class FieldList extends PureComponent {
return return
} }
this._getFields() this.getFields()
}
public handleGroupByTime = groupBy => {
this.props.onGroupByTime(groupBy.menuOption)
}
public handleFill = fill => {
this.props.onFill(fill)
}
public handleToggleField = field => {
const {
query,
onToggleField,
addInitialField,
initialGroupByTime: time,
isKapacitorRule,
isQuerySupportedByExplorer,
} = this.props
const {fields, groupBy} = query
if (!isQuerySupportedByExplorer) {
return
}
const initialGroupBy = {...groupBy, time}
if (!_.size(fields)) {
return isKapacitorRule
? onToggleField(field)
: addInitialField(field, initialGroupBy)
}
onToggleField(field)
}
public handleApplyFuncs = fieldFunc => {
const {
query,
removeFuncs,
applyFuncsToField,
initialGroupByTime: time,
} = this.props
const {groupBy, fields} = query
const {funcs} = fieldFunc
// If one field has no funcs, all fields must have no funcs
if (!_.size(funcs)) {
return removeFuncs(fields)
}
// If there is no groupBy time, set one
if (!groupBy.time) {
return applyFuncsToField(fieldFunc, {...groupBy, time})
}
applyFuncsToField(fieldFunc, groupBy)
}
public handleTimeShift = shift => {
this.props.onTimeShift(shift)
}
public _getFields = () => {
const {database, measurement, retentionPolicy} = this.props.query
const {source} = this.context
const {querySource} = this.props
const proxy =
_.get(querySource, ['links', 'proxy'], null) || source.links.proxy
showFieldKeys(proxy, database, measurement, retentionPolicy).then(resp => {
const {errors, fieldSets} = showFieldKeysParser(resp.data)
if (errors.length) {
console.error('Error parsing fields keys: ', errors)
}
const newFields = _.get(fieldSets, measurement, []).map(f => ({
value: f,
type: 'field',
}))
this.setState({
fields: newFields,
})
})
} }
public render() { public render() {
@ -184,7 +160,10 @@ class FieldList extends PureComponent {
fields fields
) )
const funcs = getFuncsByFieldName(fieldFunc.value, fields) const funcs: FieldFunc[] = getFuncsByFieldName(
fieldFunc.value,
fields
)
const fieldFuncs = selectedFields.length const fieldFuncs = selectedFields.length
? selectedFields ? selectedFields
: [fieldFunc] : [fieldFunc]
@ -208,51 +187,90 @@ class FieldList extends PureComponent {
</div> </div>
) )
} }
}
const {arrayOf, bool, func, shape, string} = PropTypes private handleGroupByTime = (groupBy: GroupByOption): void => {
this.props.onGroupByTime(groupBy.menuOption)
}
FieldList.defaultProps = { private handleFill = (fill: string): void => {
isKapacitorRule: false, this.props.onFill(fill)
initialGroupByTime: null, }
}
FieldList.contextTypes = { private handleToggleField = (field: Field) => {
source: shape({ const {
links: shape({ query,
proxy: string.isRequired, onToggleField,
}).isRequired, addInitialField,
}).isRequired, initialGroupByTime: time,
} isKapacitorRule,
isQuerySupportedByExplorer,
} = this.props
const {fields, groupBy} = query
if (!isQuerySupportedByExplorer) {
return
}
const initialGroupBy = {...groupBy, time}
FieldList.propTypes = { if (!_.size(fields)) {
query: shape({ return isKapacitorRule
database: string, ? onToggleField(field)
retentionPolicy: string, : addInitialField(field, initialGroupBy)
measurement: string, }
shifts: arrayOf(
shape({ onToggleField(field)
label: string, }
unit: string,
quantity: string, private handleApplyFuncs = (fieldFunc: ApplyFuncsToFieldArgs): void => {
const {
query,
removeFuncs,
applyFuncsToField,
initialGroupByTime: time,
} = this.props
const {groupBy, fields} = query
const {funcs} = fieldFunc
// If one field has no funcs, all fields must have no funcs
if (!_.size(funcs)) {
return removeFuncs(fields)
}
// If there is no groupBy time, set one
if (!groupBy.time) {
return applyFuncsToField(fieldFunc, {...groupBy, time})
}
applyFuncsToField(fieldFunc, groupBy)
}
private handleTimeShift = (shift: TimeShiftOption): void => {
this.props.onTimeShift(shift)
}
private getFields = (): void => {
const {database, measurement, retentionPolicy} = this.props.query
const {source} = this.context
const {querySource} = this.props
const proxy =
_.get(querySource, ['links', 'proxy'], null) || source.links.proxy
showFieldKeys(proxy, database, measurement, retentionPolicy).then(resp => {
const {errors, fieldSets} = showFieldKeysParser(resp.data)
if (errors.length) {
console.error('Error parsing fields keys: ', errors)
}
const newFields = _.get(fieldSets, measurement, []).map(f => ({
value: f,
type: 'field',
}))
this.setState({
fields: newFields,
}) })
), })
}).isRequired, }
onTimeShift: func,
onToggleField: func.isRequired,
onGroupByTime: func.isRequired,
onFill: func,
applyFuncsToField: func.isRequired,
isKapacitorRule: bool,
querySource: shape({
links: shape({
proxy: string.isRequired,
}).isRequired,
}),
removeFuncs: func.isRequired,
addInitialField: func,
initialGroupByTime: string,
isQuerySupportedByExplorer: bool,
} }
export default FieldList export default FieldList

View File

@ -31,6 +31,12 @@ interface State {
@ErrorHandling @ErrorHandling
class FillQuery extends PureComponent<Props, State> { class FillQuery extends PureComponent<Props, State> {
public static defaultProps: Partial<Props> = {
size: 'sm',
theme: 'blue',
value: NULL_STRING,
}
private numberInput: HTMLElement private numberInput: HTMLElement
constructor(props) { constructor(props) {
@ -51,12 +57,6 @@ class FillQuery extends PureComponent<Props, State> {
} }
} }
public static defaultProps: Partial<Props> = {
size: 'sm',
theme: 'blue',
value: NULL_STRING,
}
public render() { public render() {
const {size, theme, isDisabled} = this.props const {size, theme, isDisabled} = this.props
const {selected, currentNumberValue} = this.state const {selected, currentNumberValue} = this.state

View File

@ -8,12 +8,12 @@ import FillQuery from 'src/shared/components/FillQuery'
interface Props { interface Props {
fill: string fill: string
onFill: () => void onFill: (fill: string) => void
groupBy: GroupBy groupBy: GroupBy
shift: TimeShift shift: TimeShift
onGroupByTime: () => void onGroupByTime: (groupBy: GroupBy) => void
isKapacitorRule: boolean isKapacitorRule: boolean
onTimeShift: () => void onTimeShift: (shift: TimeShift) => void
isDisabled: boolean isDisabled: boolean
} }

View File

@ -1,9 +1,6 @@
import React from 'react' import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import {QueryConfig, Source} from 'src/types'
import {CellEditorOverlayActions} from 'src/types/dashboard'
import DatabaseList from 'src/shared/components/DatabaseList' import DatabaseList from 'src/shared/components/DatabaseList'
import MeasurementList from 'src/shared/components/MeasurementList' import MeasurementList from 'src/shared/components/MeasurementList'
import FieldList from 'src/shared/components/FieldList' import FieldList from 'src/shared/components/FieldList'
@ -12,10 +9,8 @@ const actionBinder = (id, action) => (...args) => action(id, ...args)
const SchemaExplorer = ({ const SchemaExplorer = ({
query, query,
query: {id},
source, source,
initialGroupByTime, initialGroupByTime,
isQuerySupportedByExplorer,
actions: { actions: {
fill, fill,
timeShift, timeShift,
@ -30,7 +25,11 @@ const SchemaExplorer = ({
applyFuncsToField, applyFuncsToField,
toggleTagAcceptance, toggleTagAcceptance,
}, },
}) => ( isQuerySupportedByExplorer = true,
}) => {
const {id} = query
return (
<div className="query-builder"> <div className="query-builder">
<DatabaseList <DatabaseList
query={query} query={query}
@ -62,7 +61,8 @@ const SchemaExplorer = ({
isQuerySupportedByExplorer={isQuerySupportedByExplorer} isQuerySupportedByExplorer={isQuerySupportedByExplorer}
/> />
</div> </div>
) )
}
const {bool, func, shape, string} = PropTypes const {bool, func, shape, string} = PropTypes

View File

@ -2,10 +2,11 @@ import React, {SFC} from 'react'
import Dropdown from 'src/shared/components/Dropdown' import Dropdown from 'src/shared/components/Dropdown'
import {TIME_SHIFTS} from 'src/shared/constants/timeShift' import {TIME_SHIFTS} from 'src/shared/constants/timeShift'
import {TimeShift} from 'src/types'
interface Props { interface Props {
selected: string selected: string
onChooseTimeShift: () => void onChooseTimeShift: (timeShift: TimeShift) => void
isDisabled: boolean isDisabled: boolean
} }

View File

@ -42,6 +42,12 @@ export const firstFieldName = fields => _.head(fieldNamesDeep(fields))
export const hasField = (fieldName, fields) => export const hasField = (fieldName, fields) =>
fieldNamesDeep(fields).some(f => f === fieldName) fieldNamesDeep(fields).some(f => f === fieldName)
/**
* getAllFields and funcs with fieldName
* @param {string} fieldName
* @param {FieldFunc[]} fields
* @returns {FieldFunc[]}
*/
// getAllFields and funcs with fieldName // getAllFields and funcs with fieldName
export const getFieldsWithName = (fieldName, fields) => export const getFieldsWithName = (fieldName, fields) =>
getFieldsDeep(fields).filter(f => f.value === fieldName) getFieldsDeep(fields).filter(f => f.value === fieldName)

View File

@ -77,18 +77,20 @@ export interface Template {
values: TemplateValue[] values: TemplateValue[]
} }
export type CellEditorOverlayActionsFunc = (id: string, ...args: any[]) => any
export interface CellEditorOverlayActions { export interface CellEditorOverlayActions {
chooseNamespace: () => void chooseNamespace: CellEditorOverlayActionsFunc
chooseMeasurement: () => void chooseMeasurement: CellEditorOverlayActionsFunc
applyFuncsToField: () => void applyFuncsToField: CellEditorOverlayActionsFunc
chooseTag: () => void chooseTag: CellEditorOverlayActionsFunc
groupByTag: () => void groupByTag: CellEditorOverlayActionsFunc
toggleField: () => void toggleField: CellEditorOverlayActionsFunc
groupByTime: () => void groupByTime: CellEditorOverlayActionsFunc
toggleTagAcceptance: () => void toggleTagAcceptance: CellEditorOverlayActionsFunc
fill: () => void fill: CellEditorOverlayActionsFunc
editRawTextAsync: () => void editRawTextAsync: CellEditorOverlayActionsFunc
addInitialField: () => void addInitialField: CellEditorOverlayActionsFunc
removeFuncs: () => void removeFuncs: CellEditorOverlayActionsFunc
timeShift: () => void timeShift: CellEditorOverlayActionsFunc
} }

View File

@ -1,6 +1,13 @@
import {AuthLinks, Organization, Role, User, Me} from './auth' import {AuthLinks, Organization, Role, User, Me} from './auth'
import {Template, Cell, CellQuery, Legend} from './dashboard' import {Template, Cell, CellQuery, Legend} from './dashboard'
import {GroupBy, QueryConfig, Status, TimeRange, TimeShift} from './query' import {
GroupBy,
QueryConfig,
Status,
TimeRange,
TimeShift,
Field,
} from './query'
import {AlertRule, Kapacitor, Task} from './kapacitor' import {AlertRule, Kapacitor, Task} from './kapacitor'
import {Source, SourceLinks} from './sources' import {Source, SourceLinks} from './sources'
import {DropdownAction, DropdownItem} from './shared' import {DropdownAction, DropdownItem} from './shared'
@ -18,6 +25,7 @@ export {
Status, Status,
QueryConfig, QueryConfig,
TimeShift, TimeShift,
Field,
GroupBy, GroupBy,
AlertRule, AlertRule,
Kapacitor, Kapacitor,