feat(ui/dataLoaders): Add telegraf plugin information step with name input

pull/11522/head
Palak Bhojani 2019-01-22 12:03:48 -08:00 committed by Iris Scholten
parent cfc5291e9e
commit 294614f57e
17 changed files with 193 additions and 128 deletions

View File

@ -52,7 +52,7 @@ export interface DataLoaderStepProps {
onSetCurrentStepIndex: (stepNumber: number) => void
onIncrementCurrentStepIndex: () => void
onDecrementCurrentStepIndex: () => void
onSetSubstepIndex: (index: number, subStep: number | 'streaming') => void
onSetSubstepIndex: (index: number, subStep: Substep) => void
notify: (message: Notification | NotificationFunc) => void
onCompleteSetup: () => void
onExit: () => void
@ -227,22 +227,34 @@ class DataLoadersWizard extends PureComponent<Props> {
return isStreaming && isNotEmpty && isConfigStep
}
private handleClickSideBarTab = (telegrafPluginID: string) => {
private handleClickSideBarTab = (tabID: string) => {
const {
onSetSubstepIndex,
onSetActiveTelegrafPlugin,
dataLoaders: {telegrafPlugins},
substep,
onSetPluginConfiguration,
} = this.props
if (!_.isNaN(Number(substep))) {
onSetPluginConfiguration(_.get(telegrafPlugins, `${substep}.name`, ''))
}
if (tabID === 'config') {
onSetSubstepIndex(DataLoaderStep.Configure, tabID)
onSetActiveTelegrafPlugin('')
return
}
const index = Math.max(
_.findIndex(telegrafPlugins, plugin => {
return plugin.name === telegrafPluginID
return plugin.name === tabID
}),
0
)
onSetSubstepIndex(DataLoaderStep.Configure, index)
onSetActiveTelegrafPlugin(telegrafPluginID)
onSetActiveTelegrafPlugin(tabID)
}
private get stepProps(): DataLoaderStepProps {

View File

@ -65,6 +65,7 @@ export type Action =
| SetScraperTargetURL
| SetScraperTargetID
| ClearDataLoaders
| SetTelegrafConfigName
interface SetDataLoadersType {
type: 'SET_DATA_LOADERS_TYPE'
@ -86,6 +87,16 @@ export const clearDataLoaders = (): ClearDataLoaders => ({
type: 'CLEAR_DATA_LOADERS',
})
interface SetTelegrafConfigName {
type: 'SET_TELEGRAF_CONFIG_NAME'
payload: {name: string}
}
export const setTelegrafConfigName = (name: string): SetTelegrafConfigName => ({
type: 'SET_TELEGRAF_CONFIG_NAME',
payload: {name},
})
interface UpdateTelegrafPluginConfig {
type: 'UPDATE_TELEGRAF_PLUGIN_CONFIG'
payload: {name: string; field: string; value: string}
@ -284,7 +295,7 @@ export const createOrUpdateTelegrafConfigAsync = (authToken: string) => async (
) => {
const {
dataLoading: {
dataLoaders: {telegrafPlugins, telegrafConfigID},
dataLoaders: {telegrafPlugins, telegrafConfigID, telegrafConfigName},
steps: {org, bucket, orgID},
},
} = getState()
@ -311,13 +322,17 @@ export const createOrUpdateTelegrafConfigAsync = (authToken: string) => async (
const telegrafConfig = await getTelegrafConfig(telegrafConfigID)
const id = _.get(telegrafConfig, 'id', '')
await updateTelegrafConfig(id, {...telegrafConfig, plugins})
await updateTelegrafConfig(id, {
...telegrafConfig,
name: telegrafConfigName,
plugins,
})
dispatch(setTelegrafConfigID(id))
return
}
const telegrafRequest: TelegrafRequest = {
name: 'new config',
name: telegrafConfigName,
agent: {collectionInterval: DEFAULT_COLLECTION_INTERVAL},
organizationID: orgID,
plugins,

View File

@ -18,11 +18,7 @@ import {
// Types
import {DataLoaderStepProps} from 'src/dataLoaders/components/DataLoadersWizard'
import {
TelegrafPlugin,
DataLoaderType,
DataLoaderStep,
} from 'src/types/v2/dataLoaders'
import {TelegrafPlugin, DataLoaderType} from 'src/types/v2/dataLoaders'
import {Bucket} from 'src/api'
export interface OwnProps extends DataLoaderStepProps {
@ -74,21 +70,14 @@ export class ConfigureDataSourceStep extends PureComponent<Props> {
onAddConfigValue={onAddConfigValue}
onRemoveConfigValue={onRemoveConfigValue}
dataLoaderType={type}
currentIndex={+substep}
substepIndex={substep}
onSetConfigArrayValue={onSetConfigArrayValue}
onClickNext={this.handleNext}
onClickPrevious={this.handlePrevious}
onClickSkip={this.jumpToCompletionStep}
/>
)
}
private jumpToCompletionStep = () => {
const {onSetCurrentStepIndex} = this.props
onSetCurrentStepIndex(DataLoaderStep.Verify)
}
private handleNext = async () => {
const {
onIncrementCurrentStepIndex,
@ -97,31 +86,23 @@ export class ConfigureDataSourceStep extends PureComponent<Props> {
telegrafPlugins,
substep,
currentStepIndex,
onSetSubstepIndex,
type,
onExit,
onSetSubstepIndex,
} = this.props
const index = +substep
const telegrafPlugin = _.get(telegrafPlugins, `${index}.name`)
onSetPluginConfiguration(telegrafPlugin)
if (type === DataLoaderType.Streaming) {
if (index >= telegrafPlugins.length - 1) {
onIncrementCurrentStepIndex()
onSetActiveTelegrafPlugin('')
} else {
const name = _.get(telegrafPlugins, `${index + 1}.name`, '')
onSetActiveTelegrafPlugin(name)
onSetSubstepIndex(+currentStepIndex, index + 1)
}
return
} else if (
type === DataLoaderType.Scraping &&
currentStepIndex === DataLoaderStep.Configure
) {
if (type === DataLoaderType.Scraping) {
onExit()
return
}
if (type === DataLoaderType.Streaming && !_.isNaN(Number(substep))) {
const index = +substep
const telegrafPlugin = _.get(telegrafPlugins, `${index}.name`)
onSetPluginConfiguration(telegrafPlugin)
onSetActiveTelegrafPlugin('')
onSetSubstepIndex(currentStepIndex, 'config')
return
}
onIncrementCurrentStepIndex()
@ -132,28 +113,14 @@ export class ConfigureDataSourceStep extends PureComponent<Props> {
type,
substep,
currentStepIndex,
onSetActiveTelegrafPlugin,
onSetPluginConfiguration,
telegrafPlugins,
onSetSubstepIndex,
onDecrementCurrentStepIndex,
} = this.props
const index = +substep
const telegrafPlugin = _.get(telegrafPlugins, `${index}.name`)
if (type === DataLoaderType.Streaming) {
onSetPluginConfiguration(telegrafPlugin)
if (index > 0) {
const name = _.get(telegrafPlugins, `${index - 1}.name`)
onSetActiveTelegrafPlugin(name)
onSetSubstepIndex(+currentStepIndex, index - 1)
} else {
onSetActiveTelegrafPlugin('')
if (substep === 'config') {
onSetSubstepIndex(+currentStepIndex - 1, 'streaming')
}
return
}

View File

@ -18,12 +18,12 @@ import {
} from 'src/onboarding/actions/dataLoaders'
// Types
import {TelegrafPlugin, DataLoaderType} from 'src/types/v2/dataLoaders'
import {TelegrafPlugin, DataLoaderType, Substep} from 'src/types/v2/dataLoaders'
import {Bucket} from 'src/api'
export interface Props {
telegrafPlugins: TelegrafPlugin[]
currentIndex: number
substepIndex: Substep
onUpdateTelegrafPluginConfig: typeof updateTelegrafPluginConfig
onAddConfigValue: typeof addConfigValue
onRemoveConfigValue: typeof removeConfigValue
@ -35,7 +35,6 @@ export interface Props {
onSetConfigArrayValue: typeof setConfigArrayValue
onClickNext: () => void
onClickPrevious: () => void
onClickSkip: () => void
}
@ErrorHandling
@ -45,7 +44,7 @@ class ConfigureDataSourceSwitcher extends PureComponent<Props> {
bucket,
org,
telegrafPlugins,
currentIndex,
substepIndex,
dataLoaderType,
onUpdateTelegrafPluginConfig,
onAddConfigValue,
@ -53,7 +52,6 @@ class ConfigureDataSourceSwitcher extends PureComponent<Props> {
onSetConfigArrayValue,
onClickNext,
onClickPrevious,
onClickSkip,
buckets,
} = this.props
@ -65,12 +63,11 @@ class ConfigureDataSourceSwitcher extends PureComponent<Props> {
onUpdateTelegrafPluginConfig={onUpdateTelegrafPluginConfig}
onRemoveConfigValue={onRemoveConfigValue}
telegrafPlugins={telegrafPlugins}
currentIndex={currentIndex}
substepIndex={substepIndex}
onAddConfigValue={onAddConfigValue}
onSetConfigArrayValue={onSetConfigArrayValue}
onClickNext={onClickNext}
onClickPrevious={onClickPrevious}
onClickSkip={onClickSkip}
/>
</div>
)

View File

@ -12,9 +12,6 @@ import OnboardingButtons from 'src/onboarding/components/OnboardingButtons'
import {telegrafPluginsInfo} from 'src/onboarding/constants/pluginConfigs'
import {telegrafPlugin} from 'mocks/dummyData'
// Dummy Data
import {cpuTelegrafPlugin} from 'mocks/dummyData'
// Types
import {TelegrafPluginInputCpu, TelegrafPluginInputRedis} from 'src/api'
@ -79,17 +76,4 @@ describe('Onboarding.Components.ConfigureStep.Streaming.PluginConfigForm', () =>
expect(configFieldSwitchers.length).toBe(fields.length)
})
})
describe('if skip button is clicked', () => {
it('renders the correct skip button text for streaming sources', () => {
const {wrapper} = setup({
telegrafPlugins: [cpuTelegrafPlugin],
params: {stepID: '3', substepID: 'streaming'},
})
const skipButton = wrapper.find('[data-test="skip"]')
expect(skipButton.prop('text')).toBe('Skip to Verify')
})
})
})

View File

@ -28,9 +28,6 @@ interface Props {
onSetConfigArrayValue: typeof setConfigArrayValue
onClickNext: () => void
telegrafPlugins: TelegrafPlugin[]
currentIndex: number
onClickPrevious: () => void
onClickSkip: () => void
}
class PluginConfigForm extends PureComponent<Props> {
@ -43,8 +40,6 @@ class PluginConfigForm extends PureComponent<Props> {
onAddConfigValue,
onRemoveConfigValue,
onUpdateTelegrafPluginConfig,
onClickPrevious,
onClickSkip,
} = this.props
return (
<Form onSubmit={this.props.onClickNext}>
@ -72,13 +67,7 @@ class PluginConfigForm extends PureComponent<Props> {
</div>
</FancyScrollbar>
</div>
<OnboardingButtons
onClickBack={onClickPrevious}
onClickSkip={onClickSkip}
showSkip={true}
skipButtonText={'Skip to Verify'}
autoFocusNext={this.autoFocus}
/>
<OnboardingButtons autoFocusNext={this.autoFocus} />
</Form>
)
}

View File

@ -14,7 +14,7 @@ import {TelegrafPluginInputCpu} from 'src/api'
const setup = (override = {}) => {
const props = {
telegrafPlugins: [],
currentIndex: 0,
substepIndex: 0,
authToken: token,
onUpdateTelegrafPluginConfig: jest.fn(),
onAddConfigValue: jest.fn(),

View File

@ -18,18 +18,18 @@ import {
} from 'src/onboarding/actions/dataLoaders'
// Types
import {TelegrafPlugin} from 'src/types/v2/dataLoaders'
import {TelegrafPlugin, Substep} from 'src/types/v2/dataLoaders'
import TelegrafPluginInstructions from 'src/onboarding/components/configureStep/streaming/TelegrafPluginInstructions'
interface Props {
telegrafPlugins: TelegrafPlugin[]
onUpdateTelegrafPluginConfig: typeof updateTelegrafPluginConfig
onAddConfigValue: typeof addConfigValue
onRemoveConfigValue: typeof removeConfigValue
currentIndex: number
substepIndex: Substep
onSetConfigArrayValue: typeof setConfigArrayValue
onClickNext: () => void
onClickPrevious: () => void
onClickSkip: () => void
}
class PluginConfigSwitcher extends PureComponent<Props> {
@ -41,12 +41,18 @@ class PluginConfigSwitcher extends PureComponent<Props> {
onSetConfigArrayValue,
onClickNext,
telegrafPlugins,
currentIndex,
substepIndex,
onClickPrevious,
onClickSkip,
} = this.props
if (this.currentTelegrafPlugin) {
if (substepIndex === 'config') {
return (
<TelegrafPluginInstructions
onClickNext={onClickNext}
onClickPrevious={onClickPrevious}
/>
)
} else if (this.currentTelegrafPlugin) {
return (
<PluginConfigForm
telegrafPlugin={this.currentTelegrafPlugin}
@ -57,18 +63,16 @@ class PluginConfigSwitcher extends PureComponent<Props> {
onSetConfigArrayValue={onSetConfigArrayValue}
onClickNext={onClickNext}
telegrafPlugins={telegrafPlugins}
currentIndex={currentIndex}
onClickPrevious={onClickPrevious}
onClickSkip={onClickSkip}
/>
)
} else {
return <EmptyDataSourceState />
}
return <EmptyDataSourceState />
}
private get currentTelegrafPlugin(): TelegrafPlugin {
const {currentIndex, telegrafPlugins} = this.props
return _.get(telegrafPlugins, `${currentIndex}`, null)
const {substepIndex, telegrafPlugins} = this.props
return _.get(telegrafPlugins, `${substepIndex}`, null)
}
private get configFields() {

View File

@ -0,0 +1,80 @@
// Libraries
import React, {PureComponent, ChangeEvent} from 'react'
import {connect} from 'react-redux'
import {AppState} from 'src/types/v2/index'
import {Form, Input, InputType, ComponentSize} from 'src/clockface'
import FancyScrollbar from 'src/shared/components/fancy_scrollbar/FancyScrollbar'
import OnboardingButtons from '../../OnboardingButtons'
import {setTelegrafConfigName} from 'src/onboarding/actions/dataLoaders'
interface OwnProps {
onClickNext: () => void
onClickPrevious: () => void
}
interface DispatchProps {
onSetTelegrafConfigName: typeof setTelegrafConfigName
}
interface StateProps {
telegrafConfigName: string
}
type Props = OwnProps & DispatchProps & StateProps
class TelegrafPluginInstructions extends PureComponent<Props> {
public render() {
const {onClickPrevious, onClickNext, telegrafConfigName} = this.props
return (
<Form onSubmit={onClickNext}>
<div className="wizard-step--scroll-area">
<FancyScrollbar autoHide={false}>
<div className="wizard-step--scroll-content">
<h3 className="wizard-step--title">
Telegraf Configuration Information
</h3>
<h5 className="wizard-step--sub-title">
Telegraf is a plugin based data collection agent. Click on the
plugin names to the left in order to configure the selected
plugins. For more information about Telegraf Plugins, see
documentation.
</h5>
<Form.Element label="Telegraf Configuration Name">
<Input
type={InputType.Text}
value={telegrafConfigName}
onChange={this.handleNameInput}
titleText="Telegraf Configuration Name"
size={ComponentSize.Medium}
autoFocus={true}
/>
</Form.Element>
</div>
</FancyScrollbar>
</div>
<OnboardingButtons onClickBack={onClickPrevious} />
</Form>
)
}
private handleNameInput = (e: ChangeEvent<HTMLInputElement>) => {
this.props.onSetTelegrafConfigName(e.target.value)
}
}
const mstp = ({
dataLoading: {
dataLoaders: {telegrafConfigName},
},
}: AppState): StateProps => {
return {
telegrafConfigName,
}
}
const mdtp: DispatchProps = {
onSetTelegrafConfigName: setTelegrafConfigName,
}
export default connect<StateProps, DispatchProps, OwnProps>(
mstp,
mdtp
)(TelegrafPluginInstructions)

View File

@ -132,21 +132,20 @@ export class SelectDataSourceStep extends PureComponent<Props> {
private handleClickNext = () => {
const {
currentStepIndex,
telegrafPlugins,
onSetActiveTelegrafPlugin,
onSetSubstepIndex,
} = this.props
if (this.props.type === DataLoaderType.Streaming && !this.isStreaming) {
const isTypeSelectionStep =
this.props.type === DataLoaderType.Streaming && !this.isStreaming
if (isTypeSelectionStep) {
onSetSubstepIndex(currentStepIndex, 'streaming')
onSetActiveTelegrafPlugin('')
return
}
if (this.isStreaming) {
const name = _.get(telegrafPlugins, '0.name', '')
onSetActiveTelegrafPlugin(name)
onSetSubstepIndex(currentStepIndex + 1, 0)
onSetSubstepIndex(currentStepIndex + 1, 'config')
return
}

View File

@ -99,16 +99,6 @@ export class VerifyDataStep extends PureComponent<Props> {
return selectedBucket || bucket
}
private get previousStepName() {
const {telegrafPlugins, type} = this.props
if (type === DataLoaderType.Streaming) {
return _.get(telegrafPlugins, `${telegrafPlugins.length - 1}.name`, '')
}
return type
}
private handleIncrementStep = () => {
const {onExit} = this.props
onExit()
@ -116,7 +106,6 @@ export class VerifyDataStep extends PureComponent<Props> {
private handleDecrementStep = () => {
const {
telegrafPlugins,
onSetActiveTelegrafPlugin,
onDecrementCurrentStepIndex,
onSetSubstepIndex,
@ -125,12 +114,11 @@ export class VerifyDataStep extends PureComponent<Props> {
} = this.props
if (type === DataLoaderType.Streaming) {
onSetSubstepIndex(stepIndex - 1, telegrafPlugins.length - 1 || 0)
onSetActiveTelegrafPlugin(this.previousStepName)
onSetSubstepIndex(stepIndex - 1, 'config')
} else {
onDecrementCurrentStepIndex()
onSetActiveTelegrafPlugin('')
}
onSetActiveTelegrafPlugin('')
}
}

View File

@ -22,6 +22,7 @@ import {
setScraperTargetBucket,
setScraperTargetURL,
setScraperTargetID,
setTelegrafConfigName,
} from 'src/onboarding/actions/dataLoaders'
// Mock Data
@ -401,6 +402,22 @@ describe('dataLoader reducer', () => {
expect(actual).toEqual(expected)
})
it('can set telegraf config name ', () => {
const actual = dataLoadersReducer(
{
...INITIAL_STATE,
},
setTelegrafConfigName('myConfig')
)
const expected = {
...INITIAL_STATE,
telegrafConfigName: 'myConfig',
}
expect(actual).toEqual(expected)
})
it('can set scraperTarget bucket', () => {
const actual = dataLoadersReducer(
{

View File

@ -36,6 +36,7 @@ export const INITIAL_STATE: DataLoadersState = {
telegrafConfigID: null,
pluginBundles: [],
scraperTarget: {bucket: '', url: QUICKSTART_SCRAPER_TARGET_URL},
telegrafConfigName: 'new config',
}
export default (state = INITIAL_STATE, action: Action): DataLoadersState => {
@ -264,6 +265,11 @@ export default (state = INITIAL_STATE, action: Action): DataLoadersState => {
return {...tp}
}),
}
case 'SET_TELEGRAF_CONFIG_NAME':
return {
...state,
telegrafConfigName: action.payload.name,
}
case 'SET_SCRAPER_TARGET_BUCKET':
const {bucket} = action.payload
return {

View File

@ -13,7 +13,7 @@ import {getDeep} from 'src/utils/wrappers'
interface Props {
collectors: Telegraf[]
emptyState: JSX.Element
onDownloadConfig: (telegrafID: string) => void
onDownloadConfig: (telegrafID: string, telegrafName: string) => void
onDelete: (telegrafID: string) => void
}

View File

@ -16,7 +16,7 @@ import {Telegraf} from 'src/api'
interface Props {
collector: Telegraf
bucket: string
onDownloadConfig: (telegrafID: string) => void
onDownloadConfig: (telegrafID: string, telegrafName: string) => void
onDelete: (telegrafID: string) => void
}
@ -50,7 +50,10 @@ export default class CollectorRow extends PureComponent<Props> {
}
private handleDownloadConfig = (): void => {
this.props.onDownloadConfig(this.props.collector.id)
this.props.onDownloadConfig(
this.props.collector.id,
this.props.collector.name
)
}
private handleDeleteConfig = (): void => {
this.props.onDelete(this.props.collector.id)

View File

@ -173,10 +173,13 @@ export default class Collectors extends PureComponent<Props, State> {
)
}
private handleDownloadConfig = async (telegrafID: string) => {
private handleDownloadConfig = async (
telegrafID: string,
telegrafName: string
) => {
try {
const config = await getTelegrafConfigTOML(telegrafID)
downloadTextFile(config, 'config.toml')
downloadTextFile(config, `${telegrafName || 'config'}.toml`)
} catch (error) {
notify(getTelegrafConfigFailed())
}

View File

@ -59,6 +59,7 @@ export interface DataLoadersState {
lineProtocolBody: string
precision: WritePrecision
scraperTarget: ScraperTarget
telegrafConfigName: string
}
export enum ConfigurationState {
@ -192,4 +193,4 @@ export interface TelegrafPluginInfo {
}
}
export type Substep = number | 'streaming'
export type Substep = number | 'streaming' | 'config'