Move dataloading into admin ui

Co-authored-by: Daniel Campbell <metalwhirlwind@gmail.com>
pull/11174/head
Iris Scholten 2019-01-15 11:58:10 -08:00
parent 073b034c24
commit 4918d7ae67
46 changed files with 1000 additions and 543 deletions

View File

@ -4168,7 +4168,7 @@ components:
type: string
rp:
type: string
orgID:
organizationID:
type: string
retentionRules:
type: array

View File

@ -4985,7 +4985,7 @@ components:
type: string
name:
type: string
orgID:
organizationID:
type: string
organization:
type: string

View File

@ -343,7 +343,7 @@ export interface Bucket {
* @type {string}
* @memberof Bucket
*/
orgID?: string;
organizationID?: string;
/**
* rules to expire or retain data. No rules means data never expires.
* @type {Array<BucketRetentionRules>}

View File

@ -3,6 +3,20 @@
------------------------------------------------------------------------------
*/
.wizard-overlay {
height: calc(100vh - 206px);
width: 100%;
position: relative;
display: inline-flex;
flex-direction: column;
>.wizard-contents {
width: 100%;
min-width: 100%;
flex-grow: 1;
margin: 0;
}
}
.wizard--progress-bar {
display: inline-flex;
justify-content: center;

View File

@ -14,6 +14,7 @@ interface Props {
stepStatuses: StepStatus[]
stepTitles: string[]
stepSkippable: boolean[]
hideFirstStep?: boolean
}
@ErrorHandling
@ -68,13 +69,18 @@ class ProgressBar extends PureComponent<Props, null> {
}
private get WizardProgress(): JSX.Element[] {
const {stepStatuses, stepTitles, currentStepIndex} = this.props
const {
hideFirstStep,
stepStatuses,
stepTitles,
currentStepIndex,
} = this.props
const lastIndex = stepStatuses.length - 1
const progressBar: JSX.Element[] = stepStatuses.reduce(
(acc, stepStatus, i) => {
if (i === 0) {
if (hideFirstStep && i === 0) {
return [...acc]
}

View File

@ -0,0 +1,9 @@
/*
Wizard Overlay Styles
*/
.wizard-overlay {
>.wizard-contents {
margin: 0;
}
}

View File

@ -19,22 +19,25 @@ interface Props {
resetWizardState: () => void
maxWidth?: number
jumpStep: number
onDismis: () => void
}
@ErrorHandling
class WizardOverlay extends PureComponent<Props> {
public static defaultProps: Partial<Props> = {
maxWidth: 800,
maxWidth: 1200,
}
public render() {
const {visible, title, maxWidth} = this.props
const {visible, title, maxWidth, children, onDismis} = this.props
return (
<OverlayTechnology visible={visible}>
<OverlayContainer maxWidth={maxWidth}>
<OverlayHeading title={title} />
<OverlayBody>wizard</OverlayBody>
<OverlayHeading title={title} onDismiss={onDismis} />
<OverlayBody>
<div className="wizard-overlay">{children}</div>
</OverlayBody>
</OverlayContainer>
</OverlayTechnology>
)

View File

@ -17,6 +17,7 @@ import Panel from './components/panel/Panel'
import Radio from './components/radio_buttons/RadioButtons'
import SlideToggle from './components/slide_toggle/SlideToggle'
import WizardFullScreen from './components/wizard/WizardFullScreen'
import WizardOverlay from './components/wizard/WizardOverlay'
import WizardProgressHeader from './components/wizard/WizardProgressHeader'
import ProgressBar from './components/wizard/ProgressBar'
import ComponentSpacer from './components/component_spacer/ComponentSpacer'
@ -101,4 +102,5 @@ export {
Stack,
WizardFullScreen,
WizardProgressHeader,
WizardOverlay,
}

View File

@ -18,6 +18,7 @@
@import 'components/wizard/WizardFullScreen';
@import 'components/wizard/WizardProgressHeader';
@import 'components/wizard/ProgressBar';
@import 'components/wizard/WizardOverlay';
@import 'components/component_spacer/ComponentSpacer';
@import 'components/empty_state/EmptyState';
@import 'components/spinners/SparkleSpinner';

View File

@ -0,0 +1,335 @@
// Libraries
import React, {PureComponent} from 'react'
import {connect} from 'react-redux'
import _ from 'lodash'
// Components
import {ErrorHandling} from 'src/shared/decorators/errors'
import {WizardProgressHeader, ProgressBar} from 'src/clockface'
import WizardOverlay from 'src/clockface/components/wizard/WizardOverlay'
import StepSwitcher from 'src/dataLoaders/components/StepSwitcher'
// Actions
import {notify as notifyAction} from 'src/shared/actions/notifications'
import {
setBucketInfo,
setStepStatus,
incrementCurrentStepIndex,
decrementCurrentStepIndex,
setCurrentStepIndex,
setSubstepIndex,
clearSteps,
} from 'src/onboarding/actions/steps'
import {
setDataLoadersType,
updateTelegrafPluginConfig,
addConfigValue,
removeConfigValue,
setActiveTelegrafPlugin,
setPluginConfiguration,
createOrUpdateTelegrafConfigAsync,
addPluginBundleWithPlugins,
removePluginBundleWithPlugins,
setConfigArrayValue,
clearDataLoaders,
} from 'src/onboarding/actions/dataLoaders'
// Constants
import {StepStatus} from 'src/clockface/constants/wizard'
// Types
import {Links} from 'src/types/v2/links'
import {
DataLoadersState,
DataLoaderType,
Substep,
} from 'src/types/v2/dataLoaders'
import {Notification, NotificationFunc} from 'src/types'
import {AppState} from 'src/types/v2'
import {Bucket} from 'src/api'
import PluginsSideBar from 'src/onboarding/components/PluginsSideBar'
export interface DataLoaderStepProps {
links: Links
currentStepIndex: number
substep: Substep
onSetCurrentStepIndex: (stepNumber: number) => void
onIncrementCurrentStepIndex: () => void
onDecrementCurrentStepIndex: () => void
onSetStepStatus: (index: number, status: StepStatus) => void
onSetSubstepIndex: (index: number, subStep: number | 'streaming') => void
stepStatuses: StepStatus[]
stepTitles: string[]
notify: (message: Notification | NotificationFunc) => void
onCompleteSetup: () => void
onExit: () => void
}
interface OwnProps {
onCompleteSetup: () => void
visible: boolean
bucket: Bucket
}
interface DispatchProps {
notify: (message: Notification | NotificationFunc) => void
onSetBucketInfo: typeof setBucketInfo
onSetStepStatus: typeof setStepStatus
onSetDataLoadersType: typeof setDataLoadersType
onAddPluginBundle: typeof addPluginBundleWithPlugins
onRemovePluginBundle: typeof removePluginBundleWithPlugins
onUpdateTelegrafPluginConfig: typeof updateTelegrafPluginConfig
onAddConfigValue: typeof addConfigValue
onRemoveConfigValue: typeof removeConfigValue
onSetActiveTelegrafPlugin: typeof setActiveTelegrafPlugin
onSetPluginConfiguration: typeof setPluginConfiguration
onSetConfigArrayValue: typeof setConfigArrayValue
onSaveTelegrafConfig: typeof createOrUpdateTelegrafConfigAsync
onIncrementCurrentStepIndex: typeof incrementCurrentStepIndex
onDecrementCurrentStepIndex: typeof decrementCurrentStepIndex
onSetCurrentStepIndex: typeof setCurrentStepIndex
onSetSubstepIndex: typeof setSubstepIndex
onClearDataLoaders: typeof clearDataLoaders
onClearSteps: typeof clearSteps
}
interface StateProps {
links: Links
stepStatuses: StepStatus[]
dataLoaders: DataLoadersState
currentStepIndex: number
substep: Substep
username: string
}
type Props = OwnProps & StateProps & DispatchProps
@ErrorHandling
class DataLoadersWizard extends PureComponent<Props> {
public stepTitles = [
'Select Data Sources',
'Configure Data Sources',
'Verify',
]
public stepSkippable = [true, true, true]
public componentDidMount() {
const {bucket} = this.props
if (bucket) {
const {organization, organizationID, name, id} = bucket
this.props.onSetBucketInfo(organization, organizationID, name, id)
}
}
public componentDidUpdate(prevProps: Props) {
const {bucket} = this.props
const prevID = _.get(prevProps.bucket, 'id', '')
const curID = _.get(bucket, 'id', '')
const isDifferentBucket = prevID !== curID
if (isDifferentBucket && bucket) {
const {organization, organizationID, name, id} = bucket
this.props.onSetBucketInfo(organization, organizationID, name, id)
}
}
public render() {
const {
currentStepIndex,
dataLoaders,
dataLoaders: {telegrafPlugins, telegrafConfigID},
onSetDataLoadersType,
onSetActiveTelegrafPlugin,
onSetPluginConfiguration,
onUpdateTelegrafPluginConfig,
onAddConfigValue,
onRemoveConfigValue,
onSaveTelegrafConfig,
onAddPluginBundle,
onRemovePluginBundle,
notify,
onSetConfigArrayValue,
visible,
bucket,
username,
} = this.props
return (
<WizardOverlay
visible={visible}
title={'Data Loading'}
onDismis={this.handleDismiss}
>
{this.progressHeader}
<div className="wizard-contents">
<PluginsSideBar
notify={notify}
telegrafPlugins={telegrafPlugins}
telegrafConfigID={telegrafConfigID}
onTabClick={this.handleClickSideBarTab}
title="Plugins to Configure"
visible={this.sideBarVisible}
currentStepIndex={currentStepIndex}
onNewSourceClick={this.handleNewSourceClick}
/>
<div className="wizard-step--container">
<StepSwitcher
currentStepIndex={currentStepIndex}
onboardingStepProps={this.stepProps}
bucketName={_.get(bucket, 'name', '')}
dataLoaders={dataLoaders}
onSetDataLoadersType={onSetDataLoadersType}
onUpdateTelegrafPluginConfig={onUpdateTelegrafPluginConfig}
onSetActiveTelegrafPlugin={onSetActiveTelegrafPlugin}
onSetPluginConfiguration={onSetPluginConfiguration}
onAddConfigValue={onAddConfigValue}
onRemoveConfigValue={onRemoveConfigValue}
onSaveTelegrafConfig={onSaveTelegrafConfig}
onAddPluginBundle={onAddPluginBundle}
onRemovePluginBundle={onRemovePluginBundle}
onSetConfigArrayValue={onSetConfigArrayValue}
org={_.get(bucket, 'organization', '')}
username={username}
/>
</div>
</div>
</WizardOverlay>
)
}
private handleDismiss = () => {
this.props.onClearDataLoaders()
this.props.onClearSteps()
this.props.onCompleteSetup()
}
private get progressHeader(): JSX.Element {
const {stepStatuses, currentStepIndex, onSetCurrentStepIndex} = this.props
return (
<WizardProgressHeader>
<ProgressBar
currentStepIndex={currentStepIndex}
handleSetCurrentStep={onSetCurrentStepIndex}
stepStatuses={stepStatuses}
stepTitles={this.stepTitles}
stepSkippable={this.stepSkippable}
/>
</WizardProgressHeader>
)
}
private get sideBarVisible() {
const {dataLoaders} = this.props
const {telegrafPlugins, type} = dataLoaders
const isStreaming = type === DataLoaderType.Streaming
const isNotEmpty = telegrafPlugins.length > 0
return isStreaming && isNotEmpty
}
private handleNewSourceClick = () => {
const {onSetSubstepIndex, onSetActiveTelegrafPlugin} = this.props
onSetActiveTelegrafPlugin('')
onSetSubstepIndex(0, 'streaming')
}
private handleClickSideBarTab = (telegrafPluginID: string) => {
const {
onSetSubstepIndex,
onSetActiveTelegrafPlugin,
dataLoaders: {telegrafPlugins},
} = this.props
const index = Math.max(
_.findIndex(telegrafPlugins, plugin => {
return plugin.name === telegrafPluginID
}),
0
)
onSetSubstepIndex(1, index)
onSetActiveTelegrafPlugin(telegrafPluginID)
}
private get stepProps(): DataLoaderStepProps {
const {
stepStatuses,
links,
notify,
substep,
onCompleteSetup,
currentStepIndex,
onSetStepStatus,
onSetCurrentStepIndex,
onSetSubstepIndex,
onDecrementCurrentStepIndex,
onIncrementCurrentStepIndex,
} = this.props
return {
stepStatuses,
substep,
stepTitles: this.stepTitles,
currentStepIndex,
onSetCurrentStepIndex,
onSetSubstepIndex,
onIncrementCurrentStepIndex,
onDecrementCurrentStepIndex,
onSetStepStatus,
links,
notify,
onCompleteSetup,
onExit: this.handleDismiss,
}
}
}
const mstp = ({
links,
dataLoading: {
dataLoaders,
steps: {stepStatuses, currentStep, substep},
},
me: {name},
}: AppState): StateProps => ({
links,
stepStatuses,
dataLoaders,
currentStepIndex: currentStep,
substep,
username: name,
})
const mdtp: DispatchProps = {
notify: notifyAction,
onSetBucketInfo: setBucketInfo,
onSetStepStatus: setStepStatus,
onSetDataLoadersType: setDataLoadersType,
onUpdateTelegrafPluginConfig: updateTelegrafPluginConfig,
onAddConfigValue: addConfigValue,
onRemoveConfigValue: removeConfigValue,
onSetActiveTelegrafPlugin: setActiveTelegrafPlugin,
onSaveTelegrafConfig: createOrUpdateTelegrafConfigAsync,
onAddPluginBundle: addPluginBundleWithPlugins,
onRemovePluginBundle: removePluginBundleWithPlugins,
onSetPluginConfiguration: setPluginConfiguration,
onSetConfigArrayValue: setConfigArrayValue,
onIncrementCurrentStepIndex: incrementCurrentStepIndex,
onDecrementCurrentStepIndex: decrementCurrentStepIndex,
onSetCurrentStepIndex: setCurrentStepIndex,
onSetSubstepIndex: setSubstepIndex,
onClearDataLoaders: clearDataLoaders,
onClearSteps: clearSteps,
}
export default connect<StateProps, DispatchProps, OwnProps>(
mstp,
mdtp
)(DataLoadersWizard)

View File

@ -0,0 +1,119 @@
// Libraries
import React, {PureComponent} from 'react'
import _ from 'lodash'
// Components
import SelectDataSourceStep from 'src/onboarding/components/selectionStep/SelectDataSourceStep'
import ConfigureDataSourceStep from 'src/onboarding/components/configureStep/ConfigureDataSourceStep'
import VerifyDataStep from 'src/onboarding/components/verifyStep/VerifyDataStep'
import {ErrorHandling} from 'src/shared/decorators/errors'
// Actions
import {
updateTelegrafPluginConfig,
setDataLoadersType,
setActiveTelegrafPlugin,
addConfigValue,
removeConfigValue,
createOrUpdateTelegrafConfigAsync,
addPluginBundleWithPlugins,
removePluginBundleWithPlugins,
setPluginConfiguration,
setConfigArrayValue,
} from 'src/onboarding/actions/dataLoaders'
// Types
import {DataLoadersState} from 'src/types/v2/dataLoaders'
import {DataLoaderStepProps} from 'src/dataLoaders/components/DataLoadersWizard'
interface Props {
onboardingStepProps: DataLoaderStepProps
onUpdateTelegrafPluginConfig: typeof updateTelegrafPluginConfig
onAddConfigValue: typeof addConfigValue
onRemoveConfigValue: typeof removeConfigValue
onSetDataLoadersType: typeof setDataLoadersType
onSetActiveTelegrafPlugin: typeof setActiveTelegrafPlugin
onSetPluginConfiguration: typeof setPluginConfiguration
bucketName: string
dataLoaders: DataLoadersState
currentStepIndex: number
onSaveTelegrafConfig: typeof createOrUpdateTelegrafConfigAsync
onAddPluginBundle: typeof addPluginBundleWithPlugins
onRemovePluginBundle: typeof removePluginBundleWithPlugins
onSetConfigArrayValue: typeof setConfigArrayValue
org: string
username: string
}
@ErrorHandling
class StepSwitcher extends PureComponent<Props> {
public render() {
const {
currentStepIndex,
onboardingStepProps,
dataLoaders,
onSetDataLoadersType,
onSaveTelegrafConfig,
onUpdateTelegrafPluginConfig,
onSetActiveTelegrafPlugin,
onSetPluginConfiguration,
onAddConfigValue,
onRemoveConfigValue,
onAddPluginBundle,
onRemovePluginBundle,
onSetConfigArrayValue,
bucketName,
username,
org,
} = this.props
switch (currentStepIndex) {
case 0:
return (
<SelectDataSourceStep
{...onboardingStepProps}
{...dataLoaders}
onSetDataLoadersType={onSetDataLoadersType}
bucket={bucketName}
onSetActiveTelegrafPlugin={onSetActiveTelegrafPlugin}
onAddPluginBundle={onAddPluginBundle}
onRemovePluginBundle={onRemovePluginBundle}
/>
)
case 1:
return (
<ConfigureDataSourceStep
{...onboardingStepProps}
{...dataLoaders}
bucket={bucketName}
username={username}
org={org}
onUpdateTelegrafPluginConfig={onUpdateTelegrafPluginConfig}
onSetPluginConfiguration={onSetPluginConfiguration}
onAddConfigValue={onAddConfigValue}
onRemoveConfigValue={onRemoveConfigValue}
onSetActiveTelegrafPlugin={onSetActiveTelegrafPlugin}
onSetConfigArrayValue={onSetConfigArrayValue}
/>
)
case 2:
return (
<VerifyDataStep
{...onboardingStepProps}
{...dataLoaders}
bucket={bucketName}
username={username}
org={org}
onSaveTelegrafConfig={onSaveTelegrafConfig}
onSetActiveTelegrafPlugin={onSetActiveTelegrafPlugin}
onSetPluginConfiguration={onSetPluginConfiguration}
stepIndex={currentStepIndex}
/>
)
default:
return <div />
}
}
}
export default StepSwitcher

View File

@ -0,0 +1,19 @@
// Libraries
import {combineReducers} from 'redux'
// Reducers
import dataLoadersReducer from 'src/onboarding/reducers/dataLoaders'
import {DataLoadersState} from 'src/types/v2/dataLoaders'
import stepsReducer, {
DataLoadersStepsState,
} from 'src/onboarding/reducers/steps'
export interface DataLoadingState {
steps: DataLoadersStepsState
dataLoaders: DataLoadersState
}
export default combineReducers<DataLoadingState>({
steps: stepsReducer,
dataLoaders: dataLoadersReducer,
})

View File

@ -22,7 +22,7 @@ describe('Logs.LogQuery', () => {
config = buildTableQueryConfig({
id: '1',
organization: 'default',
orgID: '1',
organizationID: '1',
name: 'telegraf',
rp: 'autogen',
retentionRules: [],

View File

@ -15,7 +15,7 @@ describe('Logs.V1.queryBuilder', () => {
config = buildTableQueryConfig({
id: '1',
organization: 'default',
orgID: '1',
organizationID: '1',
name: 'telegraf',
rp: 'autogen',
retentionRules: [],

View File

@ -15,7 +15,7 @@ describe('Logs.V2.queryBuilder', () => {
config = buildTableQueryConfig({
id: '1',
organization: 'default',
orgID: '1',
organizationID: '1',
name: 'telegraf',
rp: 'autogen',
retentionRules: [],

View File

@ -64,6 +64,7 @@ export type Action =
| SetScraperTargetBucket
| SetScraperTargetURL
| SetScraperTargetID
| ClearDataLoaders
interface SetDataLoadersType {
type: 'SET_DATA_LOADERS_TYPE'
@ -77,6 +78,14 @@ export const setDataLoadersType = (
payload: {type},
})
interface ClearDataLoaders {
type: 'CLEAR_DATA_LOADERS'
}
export const clearDataLoaders = (): ClearDataLoaders => ({
type: 'CLEAR_DATA_LOADERS',
})
interface UpdateTelegrafPluginConfig {
type: 'UPDATE_TELEGRAF_PLUGIN_CONFIG'
payload: {name: string; field: string; value: string}
@ -274,12 +283,9 @@ export const createOrUpdateTelegrafConfigAsync = (authToken: string) => async (
getState: GetState
) => {
const {
onboarding: {
dataLoading: {
dataLoaders: {telegrafPlugins},
steps: {
setupParams: {org, bucket},
orgID,
},
steps: {org, bucket, orgID},
},
} = getState()
@ -410,11 +416,11 @@ export const saveScraperTarget = () => async (
getState: GetState
) => {
const {
onboarding: {
onboarding: {bucketID, orgID},
dataLoading: {
dataLoaders: {
scraperTarget: {url, id},
},
steps: {bucketID, orgID},
},
} = getState()

View File

@ -0,0 +1,87 @@
// Constants
import {StepStatus} from 'src/clockface/constants/wizard'
import {SetupSuccess, SetupError} from 'src/shared/copy/notifications'
// Actions
import {notify} from 'src/shared/actions/notifications'
// Types
import {
SetupParams,
signin as signinAJAX,
setSetupParams as setSetupParamsAJAX,
} from 'src/onboarding/apis'
export type Action =
| SetSetupParams
| SetStepStatus
| SetOrganizationID
| SetBucketID
interface SetSetupParams {
type: 'SET_SETUP_PARAMS'
payload: {setupParams: SetupParams}
}
export const setSetupParams = (setupParams: SetupParams): SetSetupParams => ({
type: 'SET_SETUP_PARAMS',
payload: {setupParams},
})
interface SetStepStatus {
type: 'SET_STEP_STATUS'
payload: {index: number; status: StepStatus}
}
export const setStepStatus = (
index: number,
status: StepStatus
): SetStepStatus => ({
type: 'SET_STEP_STATUS',
payload: {
index,
status,
},
})
interface SetOrganizationID {
type: 'SET_ORG_ID'
payload: {orgID: string}
}
const setOrganizationID = (orgID: string): SetOrganizationID => ({
type: 'SET_ORG_ID',
payload: {orgID},
})
interface SetBucketID {
type: 'SET_BUCKET_ID'
payload: {bucketID: string}
}
export const setBucketID = (bucketID: string): SetBucketID => ({
type: 'SET_BUCKET_ID',
payload: {bucketID},
})
export const setupAdmin = (setupParams: SetupParams) => async dispatch => {
try {
dispatch(setSetupParams(setupParams))
const onboardingResponse = await setSetupParamsAJAX(setupParams)
const {id: orgID} = onboardingResponse.org
const {id: bucketID} = onboardingResponse.bucket
dispatch(setOrganizationID(orgID))
dispatch(setBucketID(bucketID))
await signinAJAX({
username: setupParams.username,
password: setupParams.password,
})
dispatch(notify(SetupSuccess))
} catch (err) {
console.error(err)
dispatch(notify(SetupError))
}
}

View File

@ -1,31 +1,82 @@
// Constants
import {StepStatus} from 'src/clockface/constants/wizard'
import {SetupSuccess, SetupError} from 'src/shared/copy/notifications'
// Actions
import {notify} from 'src/shared/actions/notifications'
// Types
import {
SetupParams,
signin as signinAJAX,
setSetupParams as setSetupParamsAJAX,
} from 'src/onboarding/apis'
import {Substep} from 'src/types/v2/dataLoaders'
export type Action =
| SetSetupParams
| SetBucketInfo
| SetStepStatus
| SetOrganizationID
| SetBucketID
| IncrementCurrentStepIndex
| DecrementCurrentStepIndex
| SetCurrentStepIndex
| SetSubstepIndex
| ClearSteps
interface SetSetupParams {
type: 'SET_SETUP_PARAMS'
payload: {setupParams: SetupParams}
interface ClearSteps {
type: 'CLEAR_STEPS'
}
export const setSetupParams = (setupParams: SetupParams): SetSetupParams => ({
type: 'SET_SETUP_PARAMS',
payload: {setupParams},
export const clearSteps = (): ClearSteps => ({type: 'CLEAR_STEPS'})
interface IncrementCurrentStepIndex {
type: 'INCREMENT_CURRENT_STEP_INDEX'
}
export const incrementCurrentStepIndex = (): IncrementCurrentStepIndex => ({
type: 'INCREMENT_CURRENT_STEP_INDEX',
})
interface DecrementCurrentStepIndex {
type: 'DECREMENT_CURRENT_STEP_INDEX'
}
export const decrementCurrentStepIndex = (): DecrementCurrentStepIndex => ({
type: 'DECREMENT_CURRENT_STEP_INDEX',
})
interface SetCurrentStepIndex {
type: 'SET_CURRENT_STEP_INDEX'
payload: {index: number}
}
export const setCurrentStepIndex = (index: number): SetCurrentStepIndex => ({
type: 'SET_CURRENT_STEP_INDEX',
payload: {index},
})
interface SetSubstepIndex {
type: 'SET_SUBSTEP_INDEX'
payload: {stepIndex: number; substep: Substep}
}
export const setSubstepIndex = (
stepIndex: number,
substep: Substep
): SetSubstepIndex => ({
type: 'SET_SUBSTEP_INDEX',
payload: {stepIndex, substep},
})
interface SetBucketInfo {
type: 'SET_BUCKET_INFO'
payload: {
org: string
orgID: string
bucket: string
bucketID: string
}
}
export const setBucketInfo = (
org: string,
orgID: string,
bucket: string,
bucketID: string
): SetBucketInfo => ({
type: 'SET_BUCKET_INFO',
payload: {org, orgID, bucket, bucketID},
})
interface SetStepStatus {
@ -44,16 +95,6 @@ export const setStepStatus = (
},
})
interface SetOrganizationID {
type: 'SET_ORG_ID'
payload: {orgID: string}
}
const setOrganizationID = (orgID: string): SetOrganizationID => ({
type: 'SET_ORG_ID',
payload: {orgID},
})
interface SetBucketID {
type: 'SET_BUCKET_ID'
payload: {bucketID: string}
@ -63,25 +104,3 @@ export const setBucketID = (bucketID: string): SetBucketID => ({
type: 'SET_BUCKET_ID',
payload: {bucketID},
})
export const setupAdmin = (setupParams: SetupParams) => async dispatch => {
try {
dispatch(setSetupParams(setupParams))
const onboardingResponse = await setSetupParamsAJAX(setupParams)
const {id: orgID} = onboardingResponse.org
const {id: bucketID} = onboardingResponse.bucket
dispatch(setOrganizationID(orgID))
dispatch(setBucketID(bucketID))
await signinAJAX({
username: setupParams.username,
password: setupParams.password,
})
dispatch(notify(SetupSuccess))
} catch (err) {
console.error(err)
dispatch(notify(SetupError))
}
}

View File

@ -18,7 +18,7 @@ import OnboardingButtons from 'src/onboarding/components/OnboardingButtons'
import FancyScrollbar from 'src/shared/components/fancy_scrollbar/FancyScrollbar'
// Actions
import {setupAdmin} from 'src/onboarding/actions/steps'
import {setupAdmin} from 'src/onboarding/actions'
// Constants
import * as copy from 'src/shared/copy/notifications'
@ -43,13 +43,20 @@ class AdminStep extends PureComponent<Props, State> {
constructor(props: Props) {
super(props)
const {setupParams} = props
const username = getDeep(setupParams, 'username', '')
const password = getDeep(setupParams, 'password', '')
const confirmPassword = getDeep(setupParams, 'password', '')
const org = getDeep(setupParams, 'org', '')
const bucket = getDeep(setupParams, 'bucket', '')
this.state = {
username: getDeep(setupParams, 'username', ''),
password: getDeep(setupParams, 'password', ''),
confirmPassword: getDeep(setupParams, 'password', ''),
org: getDeep(setupParams, 'org', ''),
bucket: getDeep(setupParams, 'bucket', ''),
isAlreadySet: !!setupParams,
username,
password,
confirmPassword,
org,
bucket,
isAlreadySet: !!username && !!password && !!org && !!bucket,
isPassMismatched: false,
}
}

View File

@ -5,71 +5,25 @@ import _ from 'lodash'
// Components
import InitStep from 'src/onboarding/components/InitStep'
import AdminStep from 'src/onboarding/components/AdminStep'
import SelectDataSourceStep from 'src/onboarding/components/selectionStep/SelectDataSourceStep'
import ConfigureDataSourceStep from 'src/onboarding/components/configureStep/ConfigureDataSourceStep'
import CompletionStep from 'src/onboarding/components/CompletionStep'
import VerifyDataStep from 'src/onboarding/components/verifyStep/VerifyDataStep'
import {ErrorHandling} from 'src/shared/decorators/errors'
import FetchAuthToken from 'src/onboarding/components/verifyStep/FetchAuthToken'
// Actions
import {
updateTelegrafPluginConfig,
setDataLoadersType,
setActiveTelegrafPlugin,
addConfigValue,
removeConfigValue,
createOrUpdateTelegrafConfigAsync,
addPluginBundleWithPlugins,
removePluginBundleWithPlugins,
setPluginConfiguration,
setConfigArrayValue,
} from 'src/onboarding/actions/dataLoaders'
// Types
import {SetupParams} from 'src/onboarding/apis'
import {DataLoadersState} from 'src/types/v2/dataLoaders'
import {OnboardingStepProps} from 'src/onboarding/containers/OnboardingWizard'
import {setupAdmin} from '../actions/steps'
import {setupAdmin} from 'src/onboarding/actions'
interface Props {
onboardingStepProps: OnboardingStepProps
onUpdateTelegrafPluginConfig: typeof updateTelegrafPluginConfig
onAddConfigValue: typeof addConfigValue
onRemoveConfigValue: typeof removeConfigValue
onSetDataLoadersType: typeof setDataLoadersType
onSetActiveTelegrafPlugin: typeof setActiveTelegrafPlugin
onSetPluginConfiguration: typeof setPluginConfiguration
setupParams: SetupParams
dataLoaders: DataLoadersState
currentStepIndex: number
onSaveTelegrafConfig: typeof createOrUpdateTelegrafConfigAsync
onAddPluginBundle: typeof addPluginBundleWithPlugins
onRemovePluginBundle: typeof removePluginBundleWithPlugins
onSetConfigArrayValue: typeof setConfigArrayValue
onSetupAdmin: typeof setupAdmin
}
@ErrorHandling
class OnboardingStepSwitcher extends PureComponent<Props> {
public render() {
const {
currentStepIndex,
onboardingStepProps,
setupParams,
dataLoaders,
onSetDataLoadersType,
onSaveTelegrafConfig,
onUpdateTelegrafPluginConfig,
onSetActiveTelegrafPlugin,
onSetPluginConfiguration,
onAddConfigValue,
onRemoveConfigValue,
onAddPluginBundle,
onRemovePluginBundle,
onSetConfigArrayValue,
onSetupAdmin,
} = this.props
const {currentStepIndex, onboardingStepProps, onSetupAdmin} = this.props
switch (currentStepIndex) {
case 0:
@ -79,58 +33,6 @@ class OnboardingStepSwitcher extends PureComponent<Props> {
<AdminStep {...onboardingStepProps} onSetupAdmin={onSetupAdmin} />
)
case 2:
return (
<SelectDataSourceStep
{...onboardingStepProps}
{...dataLoaders}
onSetDataLoadersType={onSetDataLoadersType}
bucket={_.get(setupParams, 'bucket', '')}
onSetActiveTelegrafPlugin={onSetActiveTelegrafPlugin}
onAddPluginBundle={onAddPluginBundle}
onRemovePluginBundle={onRemovePluginBundle}
/>
)
case 3:
return (
<FetchAuthToken
bucket={_.get(setupParams, 'bucket', '')}
username={_.get(setupParams, 'username', '')}
>
{authToken => (
<ConfigureDataSourceStep
{...onboardingStepProps}
{...dataLoaders}
authToken={authToken}
onUpdateTelegrafPluginConfig={onUpdateTelegrafPluginConfig}
onSetPluginConfiguration={onSetPluginConfiguration}
onAddConfigValue={onAddConfigValue}
onRemoveConfigValue={onRemoveConfigValue}
onSetActiveTelegrafPlugin={onSetActiveTelegrafPlugin}
onSetConfigArrayValue={onSetConfigArrayValue}
/>
)}
</FetchAuthToken>
)
case 4:
return (
<FetchAuthToken
bucket={_.get(setupParams, 'bucket', '')}
username={_.get(setupParams, 'username', '')}
>
{authToken => (
<VerifyDataStep
{...onboardingStepProps}
{...dataLoaders}
authToken={authToken}
onSaveTelegrafConfig={onSaveTelegrafConfig}
onSetActiveTelegrafPlugin={onSetActiveTelegrafPlugin}
onSetPluginConfiguration={onSetPluginConfiguration}
stepIndex={currentStepIndex}
/>
)}
</FetchAuthToken>
)
case 5:
return <CompletionStep {...onboardingStepProps} />
default:
return <div />

View File

@ -3,7 +3,7 @@ import React from 'react'
import {shallow} from 'enzyme'
// Components
import OnboardingSideBar from 'src/onboarding/components/OnboardingSideBar'
import PluginsSideBar from 'src/onboarding/components/PluginsSideBar'
import {cpuTelegrafPlugin, diskTelegrafPlugin} from 'mocks/dummyData'
import {Button} from 'src/clockface'
import SideBarTab from 'src/onboarding/components/side_bar/SideBarTab'
@ -23,12 +23,12 @@ const setup = (override = {}) => {
...override,
}
const wrapper = shallow(<OnboardingSideBar {...props} />)
const wrapper = shallow(<PluginsSideBar {...props} />)
return {wrapper}
}
describe('OnboardingSideBar', () => {
describe('PluginsSideBar', () => {
describe('rendering', () => {
it('renders! wee!', () => {
const {wrapper} = setup({

View File

@ -41,7 +41,7 @@ const configStateToTabStatus = (cs: ConfigurationState): TabStatus => {
}
}
class OnboardingSideBar extends Component<Props> {
class PluginsSideBar extends Component<Props> {
public render() {
const {title, visible} = this.props
return (
@ -122,4 +122,4 @@ class OnboardingSideBar extends Component<Props> {
}
}
export default OnboardingSideBar
export default PluginsSideBar

View File

@ -44,13 +44,13 @@ exports[`Onboarding.Components.AdminStep renders 1`] = `
autoFocus={true}
autocomplete="off"
disabledTitleText="Username has been set"
icon="checkmark"
icon={null}
name=""
onChange={[Function]}
placeholder=""
size="md"
spellCheck={false}
status="disabled"
status="default"
titleText="Username"
value=""
/>
@ -68,13 +68,13 @@ exports[`Onboarding.Components.AdminStep renders 1`] = `
autoFocus={false}
autocomplete="off"
disabledTitleText="Password has been set"
icon="checkmark"
icon={null}
name=""
onChange={[Function]}
placeholder=""
size="md"
spellCheck={false}
status="disabled"
status="default"
titleText="Password"
type="password"
value=""
@ -93,13 +93,13 @@ exports[`Onboarding.Components.AdminStep renders 1`] = `
autoFocus={false}
autocomplete="off"
disabledTitleText="password has been set"
icon="checkmark"
icon={null}
name=""
onChange={[Function]}
placeholder=""
size="md"
spellCheck={false}
status="disabled"
status="default"
titleText="Confirm Password"
type="password"
value=""
@ -118,7 +118,7 @@ exports[`Onboarding.Components.AdminStep renders 1`] = `
autoFocus={false}
autocomplete="off"
disabledTitleText="Default organization name has been set"
icon="checkmark"
icon={null}
name=""
onChange={[Function]}
placeholder="Your organization is where everything you create lives"
@ -142,13 +142,13 @@ exports[`Onboarding.Components.AdminStep renders 1`] = `
autoFocus={false}
autocomplete="off"
disabledTitleText="Default bucket name has been set"
icon="checkmark"
icon={null}
name=""
onChange={[Function]}
placeholder="Your bucket is where you will store all your data"
size="md"
spellCheck={false}
status="disabled"
status="default"
titleText="Default Bucket Name"
value=""
/>

View File

@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`OnboardingSideBar rendering renders! wee! 1`] = `
exports[`PluginsSideBar rendering renders! wee! 1`] = `
<SideBar
title="title"
visible={true}

View File

@ -24,14 +24,15 @@ const setup = (override = {}) => {
onRemoveConfigValue: jest.fn(),
onSaveTelegrafConfig: jest.fn(),
authToken: '',
params: {
stepID: '3',
substepID: '0',
},
currentStepIndex: 3,
substep: 0,
location: null,
router: null,
routes: [],
onSetConfigArrayValue: jest.fn(),
bucket: '',
org: '',
username: '',
...override,
}

View File

@ -1,7 +1,6 @@
// Libraries
import React, {PureComponent} from 'react'
import _ from 'lodash'
import {withRouter, WithRouterProps} from 'react-router'
// Components
import {ErrorHandling} from 'src/shared/decorators/errors'
@ -21,14 +20,14 @@ import {
import {StepStatus} from 'src/clockface/constants/wizard'
// Types
import {OnboardingStepProps} from 'src/onboarding/containers/OnboardingWizard'
import {DataLoaderStepProps} from 'src/dataLoaders/components/DataLoadersWizard'
import {
TelegrafPlugin,
DataLoaderType,
ConfigurationState,
} from 'src/types/v2/dataLoaders'
export interface OwnProps extends OnboardingStepProps {
export interface OwnProps extends DataLoaderStepProps {
telegrafPlugins: TelegrafPlugin[]
onSetActiveTelegrafPlugin: typeof setActiveTelegrafPlugin
onUpdateTelegrafPluginConfig: typeof updateTelegrafPluginConfig
@ -36,18 +35,13 @@ export interface OwnProps extends OnboardingStepProps {
type: DataLoaderType
onAddConfigValue: typeof addConfigValue
onRemoveConfigValue: typeof removeConfigValue
authToken: string
onSetConfigArrayValue: typeof setConfigArrayValue
bucket: string
org: string
username: string
}
interface RouterProps {
params: {
stepID: string
substepID: string
}
}
type Props = OwnProps & WithRouterProps & RouterProps
type Props = OwnProps
@ErrorHandling
export class ConfigureDataSourceStep extends PureComponent<Props> {
@ -55,41 +49,32 @@ export class ConfigureDataSourceStep extends PureComponent<Props> {
super(props)
}
public componentDidMount() {
const {
router,
params: {stepID, substepID},
} = this.props
if (substepID === undefined) {
router.replace(`/onboarding/${stepID}/0`)
}
}
public render() {
const {
telegrafPlugins,
type,
params: {substepID},
setupParams,
substep,
onUpdateTelegrafPluginConfig,
onAddConfigValue,
onRemoveConfigValue,
onSetConfigArrayValue,
bucket,
org,
username,
} = this.props
return (
<div className="onboarding-step wizard--skippable">
<ConfigureDataSourceSwitcher
bucket={_.get(setupParams, 'bucket', '')}
org={_.get(setupParams, 'org', '')}
username={_.get(setupParams, 'username', '')}
bucket={bucket}
org={org}
username={username}
telegrafPlugins={telegrafPlugins}
onUpdateTelegrafPluginConfig={onUpdateTelegrafPluginConfig}
onAddConfigValue={onAddConfigValue}
onRemoveConfigValue={onRemoveConfigValue}
dataLoaderType={type}
currentIndex={+substepID}
currentIndex={+substep}
onSetConfigArrayValue={onSetConfigArrayValue}
onClickNext={this.handleNext}
onClickPrevious={this.handlePrevious}
@ -117,38 +102,46 @@ export class ConfigureDataSourceStep extends PureComponent<Props> {
onSetActiveTelegrafPlugin,
onSetPluginConfiguration,
telegrafPlugins,
params: {substepID, stepID},
substep,
currentStepIndex,
onSetSubstepIndex,
type,
} = this.props
const index = +substepID
const index = +substep
const telegrafPlugin = _.get(telegrafPlugins, `${index}.name`)
onSetPluginConfiguration(telegrafPlugin)
this.handleSetStepStatus()
if (type === DataLoaderType.Streaming) {
if (index >= telegrafPlugins.length - 1) {
onIncrementCurrentStepIndex()
onSetActiveTelegrafPlugin('')
} else {
const name = _.get(telegrafPlugins, `${index + 1}.name`, '')
onSetActiveTelegrafPlugin(name)
onSetSubstepIndex(+stepID, index + 1)
onSetSubstepIndex(+currentStepIndex, index + 1)
}
return
}
onIncrementCurrentStepIndex()
}
private handlePrevious = () => {
const {
type,
substep,
currentStepIndex,
onSetActiveTelegrafPlugin,
onSetPluginConfiguration,
params: {substepID, stepID},
telegrafPlugins,
onSetSubstepIndex,
onDecrementCurrentStepIndex,
} = this.props
const index = +substepID
const index = +substep
const telegrafPlugin = _.get(telegrafPlugins, `${index}.name`)
if (type === DataLoaderType.Streaming) {
@ -158,10 +151,10 @@ export class ConfigureDataSourceStep extends PureComponent<Props> {
if (index > 0) {
const name = _.get(telegrafPlugins, `${index - 1}.name`)
onSetActiveTelegrafPlugin(name)
onSetSubstepIndex(+stepID, index - 1)
onSetSubstepIndex(+currentStepIndex, index - 1)
} else {
onSetActiveTelegrafPlugin('')
onSetSubstepIndex(+stepID - 1, 'streaming')
onSetSubstepIndex(+currentStepIndex - 1, 'streaming')
}
return
@ -175,7 +168,7 @@ export class ConfigureDataSourceStep extends PureComponent<Props> {
type,
telegrafPlugins,
onSetStepStatus,
params: {stepID},
currentStepIndex,
} = this.props
if (type === DataLoaderType.Streaming) {
@ -184,14 +177,14 @@ export class ConfigureDataSourceStep extends PureComponent<Props> {
})
if (unconfigured || !telegrafPlugins.length) {
onSetStepStatus(parseInt(stepID, 10), StepStatus.Incomplete)
onSetStepStatus(currentStepIndex, StepStatus.Incomplete)
} else {
onSetStepStatus(parseInt(stepID, 10), StepStatus.Complete)
onSetStepStatus(currentStepIndex, StepStatus.Complete)
}
} else {
onSetStepStatus(parseInt(stepID, 10), StepStatus.Complete)
onSetStepStatus(currentStepIndex, StepStatus.Complete)
}
}
}
export default withRouter<OwnProps>(ConfigureDataSourceStep)
export default ConfigureDataSourceStep

View File

@ -14,7 +14,6 @@ import {
saveScraperTarget,
} from 'src/onboarding/actions/dataLoaders'
import {AppState} from 'src/types/v2/index'
import {SetupParams} from 'src/onboarding/apis'
import ScraperTarget from 'src/onboarding/components/configureStep/ScraperTarget'
interface OwnProps {
@ -32,16 +31,16 @@ interface DispatchProps {
interface StateProps {
bucket: string
url: string
setupParams: SetupParams
currentBucket: string
}
type Props = OwnProps & DispatchProps & StateProps
export class Scraping extends PureComponent<Props> {
public componentDidMount() {
const {bucket, setupParams, onSetScraperTargetBucket} = this.props
const {bucket, currentBucket, onSetScraperTargetBucket} = this.props
if (!bucket) {
onSetScraperTargetBucket(setupParams.bucket)
onSetScraperTargetBucket(currentBucket)
}
}
@ -86,11 +85,9 @@ export class Scraping extends PureComponent<Props> {
}
private get buckets(): string[] {
const {
setupParams: {bucket},
} = this.props
const {currentBucket} = this.props
return bucket ? [bucket] : []
return currentBucket ? [currentBucket] : []
}
private handleSelectBucket = (bucket: string) => {
@ -105,14 +102,16 @@ export class Scraping extends PureComponent<Props> {
}
const mstp = ({
onboarding: {
steps: {setupParams},
dataLoaders: {
scraperTarget: {bucket, url},
},
dataLoading: {
dataLoaders: {scraperTarget},
steps: {bucket},
},
}: AppState): StateProps => {
return {setupParams, bucket, url}
return {
currentBucket: bucket,
bucket: scraperTarget.bucket,
url: scraperTarget.url,
}
}
const mdtp: DispatchProps = {

View File

@ -108,7 +108,7 @@ export class LineProtocol extends PureComponent<Props> {
}
const mstp = ({
onboarding: {
dataLoading: {
dataLoaders: {lineProtocolBody, precision},
},
}: AppState): StateProps => {

View File

@ -130,7 +130,7 @@ export class LineProtocolTabs extends PureComponent<Props, State> {
}
const mstp = ({
onboarding: {
dataLoading: {
dataLoaders: {lineProtocolBody, activeLPTab, precision},
},
}: AppState) => {

View File

@ -31,10 +31,8 @@ const setup = (override = {}) => {
onSetDataLoadersType: jest.fn(),
onSetActiveTelegrafPlugin: jest.fn(),
onSetStepStatus: jest.fn(),
params: {
stepID: '2',
substepID: undefined,
},
currentStepIndex: 2,
substep: undefined,
location: null,
router: null,
routes: [],
@ -97,7 +95,8 @@ describe('Onboarding.Components.SelectionStep.SelectDataSourceStep', () => {
it('renders streaming selector with buttons', () => {
const wrapper = setup({
type: DataLoaderType.Streaming,
params: {stepID: '2', substepID: 'streaming'},
currentStepIndex: 0,
substep: 'streaming',
})
const streamingSelector = wrapper.find(StreamingSelector)
const onboardingButtons = wrapper.find(OnboardingButtons)
@ -113,7 +112,8 @@ describe('Onboarding.Components.SelectionStep.SelectDataSourceStep', () => {
it('renders back and next button with correct status', () => {
const wrapper = setup({
type: DataLoaderType.Streaming,
params: {stepID: '2', substepID: 'streaming'},
currentStepIndex: 0,
substep: 'streaming',
telegrafPlugins: [cpuTelegrafPlugin],
})
const onboardingButtons = wrapper.find(OnboardingButtons)

View File

@ -1,6 +1,5 @@
// Libraries
import React, {PureComponent} from 'react'
import {withRouter, WithRouterProps} from 'react-router'
import _ from 'lodash'
import classnames from 'classnames'
@ -23,14 +22,14 @@ import {
import {StepStatus} from 'src/clockface/constants/wizard'
// Types
import {OnboardingStepProps} from 'src/onboarding/containers/OnboardingWizard'
import {DataLoaderStepProps} from 'src/dataLoaders/components/DataLoadersWizard'
import {
TelegrafPlugin,
DataLoaderType,
BundleName,
} from 'src/types/v2/dataLoaders'
export interface OwnProps extends OnboardingStepProps {
export interface OwnProps extends DataLoaderStepProps {
bucket: string
telegrafPlugins: TelegrafPlugin[]
pluginBundles: BundleName[]
@ -42,14 +41,7 @@ export interface OwnProps extends OnboardingStepProps {
onSetStepStatus: (index: number, status: StepStatus) => void
}
interface RouterProps {
params: {
stepID: string
substepID: string
}
}
type Props = OwnProps & RouterProps & WithRouterProps
type Props = OwnProps
interface State {
showStreamingSources: boolean
@ -158,35 +150,35 @@ export class SelectDataSourceStep extends PureComponent<Props, State> {
private handleClickNext = () => {
const {
params: {stepID},
currentStepIndex,
telegrafPlugins,
onSetActiveTelegrafPlugin,
onSetSubstepIndex,
} = this.props
if (this.props.type === DataLoaderType.Streaming && !this.isStreaming) {
onSetSubstepIndex(+stepID, 'streaming')
onSetSubstepIndex(currentStepIndex, 'streaming')
onSetActiveTelegrafPlugin('')
return
}
this.handleSetStepStatus()
if (this.isStreaming) {
const name = _.get(telegrafPlugins, '0.name', '')
onSetActiveTelegrafPlugin(name)
onSetSubstepIndex(currentStepIndex + 1, 0)
return
}
this.handleSetStepStatus()
this.props.onIncrementCurrentStepIndex()
}
private handleClickBack = () => {
const {
params: {stepID},
onSetCurrentStepIndex,
} = this.props
const {currentStepIndex, onSetCurrentStepIndex} = this.props
if (this.isStreaming) {
onSetCurrentStepIndex(+stepID)
onSetCurrentStepIndex(+currentStepIndex)
return
}
@ -214,23 +206,20 @@ export class SelectDataSourceStep extends PureComponent<Props, State> {
}
private handleSetStepStatus = () => {
const {
onSetStepStatus,
params: {stepID},
} = this.props
const {onSetStepStatus, currentStepIndex} = this.props
if (
this.props.type === DataLoaderType.Streaming &&
!this.props.telegrafPlugins.length
) {
onSetStepStatus(parseInt(stepID, 10), StepStatus.Incomplete)
onSetStepStatus(currentStepIndex, StepStatus.Incomplete)
} else if (this.props.type) {
onSetStepStatus(parseInt(stepID, 10), StepStatus.Complete)
onSetStepStatus(currentStepIndex, StepStatus.Complete)
}
}
private get isStreaming(): boolean {
return this.props.params.substepID === 'streaming'
return this.props.substep === 'streaming'
}
private get skippableClassName(): string {
@ -246,4 +235,4 @@ export class SelectDataSourceStep extends PureComponent<Props, State> {
}
}
export default withRouter<OwnProps>(SelectDataSourceStep)
export default SelectDataSourceStep

View File

@ -11,23 +11,27 @@ import OnboardingButtons from 'src/onboarding/components/OnboardingButtons'
import {DataLoaderType} from 'src/types/v2/dataLoaders'
// Constants
import {defaultOnboardingStepProps, withRouterProps} from 'mocks/dummyData'
import {defaultOnboardingStepProps} from 'mocks/dummyData'
import {RemoteDataState} from 'src/types'
jest.mock('src/utils/api', () => require('src/onboarding/apis/mocks'))
const setup = (override = {}) => {
const props = {
...defaultOnboardingStepProps,
...withRouterProps,
type: DataLoaderType.Empty,
telegrafPlugins: [],
stepIndex: 4,
authToken: '',
stepIndex: 2,
substep: 0,
telegrafConfigID: '',
onSaveTelegrafConfig: jest.fn(),
onSetActiveTelegrafPlugin: jest.fn(),
onSetPluginConfiguration: jest.fn(),
lpStatus: RemoteDataState.NotStarted,
params: {stepID: '', substepID: ''},
bucket: 'defbuck',
username: 'user',
org: '',
notify: jest.fn(),
...override,
}

View File

@ -1,6 +1,5 @@
// Libraries
import React, {PureComponent} from 'react'
import {withRouter, WithRouterProps} from 'react-router'
import {connect} from 'react-redux'
import _ from 'lodash'
@ -18,37 +17,32 @@ import {
} from 'src/onboarding/actions/dataLoaders'
// Types
import {OnboardingStepProps} from 'src/onboarding/containers/OnboardingWizard'
import {DataLoaderType, TelegrafPlugin} from 'src/types/v2/dataLoaders'
import {Form} from 'src/clockface'
import {NotificationAction, RemoteDataState} from 'src/types'
import {StepStatus} from 'src/clockface/constants/wizard'
import {AppState} from 'src/types/v2'
import {DataLoaderStepProps} from 'src/dataLoaders/components/DataLoadersWizard'
export interface OwnProps extends OnboardingStepProps {
export interface OwnProps extends DataLoaderStepProps {
notify: NotificationAction
type: DataLoaderType
authToken: string
telegrafConfigID: string
telegrafPlugins: TelegrafPlugin[]
onSetActiveTelegrafPlugin: typeof setActiveTelegrafPlugin
onSetPluginConfiguration: typeof setPluginConfiguration
onSaveTelegrafConfig: typeof createOrUpdateTelegrafConfigAsync
stepIndex: number
bucket: string
username: string
org: string
}
interface StateProps {
lpStatus: RemoteDataState
}
interface RouterProps {
params: {
stepID: string
substepID: string
}
}
export type Props = RouterProps & OwnProps & WithRouterProps & StateProps
export type Props = OwnProps & StateProps
@ErrorHandling
export class VerifyDataStep extends PureComponent<Props> {
@ -64,15 +58,17 @@ export class VerifyDataStep extends PureComponent<Props> {
public render() {
const {
setupParams,
bucket,
username,
telegrafConfigID,
authToken,
type,
onSaveTelegrafConfig,
onDecrementCurrentStepIndex,
onSetStepStatus,
stepIndex,
notify,
lpStatus,
org,
} = this.props
return (
@ -85,13 +81,14 @@ export class VerifyDataStep extends PureComponent<Props> {
notify={notify}
type={type}
telegrafConfigID={telegrafConfigID}
authToken={authToken}
onSaveTelegrafConfig={onSaveTelegrafConfig}
org={_.get(setupParams, 'org', '')}
bucket={_.get(setupParams, 'bucket', '')}
org={org}
bucket={bucket}
username={username}
onSetStepStatus={onSetStepStatus}
stepIndex={stepIndex}
onDecrementCurrentStep={onDecrementCurrentStepIndex}
lpStatus={lpStatus}
/>
</div>
</FancyScrollbar>
@ -101,6 +98,7 @@ export class VerifyDataStep extends PureComponent<Props> {
onClickSkip={this.jumpToCompletionStep}
skipButtonText={'Skip'}
showSkip={true}
nextButtonText={'Finish'}
/>
</Form>
</div>
@ -118,26 +116,19 @@ export class VerifyDataStep extends PureComponent<Props> {
}
private handleIncrementStep = () => {
const {
onIncrementCurrentStepIndex,
onSetStepStatus,
type,
lpStatus,
} = this.props
const {
params: {stepID},
} = this.props
const {onSetStepStatus, type, lpStatus, onExit} = this.props
const {currentStepIndex} = this.props
if (
type === DataLoaderType.LineProtocol &&
lpStatus === RemoteDataState.Error
) {
onSetStepStatus(parseInt(stepID, 10), StepStatus.Error)
onSetStepStatus(currentStepIndex, StepStatus.Error)
} else {
onSetStepStatus(parseInt(stepID, 10), StepStatus.Complete)
onSetStepStatus(currentStepIndex, StepStatus.Complete)
}
onIncrementCurrentStepIndex()
onExit()
}
private handleDecrementStep = () => {
@ -167,13 +158,11 @@ export class VerifyDataStep extends PureComponent<Props> {
}
const mstp = ({
onboarding: {
dataLoading: {
dataLoaders: {lpStatus},
},
}: AppState): StateProps => ({
lpStatus,
})
export default withRouter<OwnProps>(
connect<StateProps, {}, OwnProps>(mstp)(VerifyDataStep)
)
export default connect<StateProps, {}, OwnProps>(mstp)(VerifyDataStep)

View File

@ -4,7 +4,6 @@ import {shallow} from 'enzyme'
// Components
import {VerifyDataSwitcher} from 'src/onboarding/components/verifyStep/VerifyDataSwitcher'
import DataStreaming from 'src/onboarding/components/verifyStep/DataStreaming'
// Types
import {DataLoaderType} from 'src/types/v2/dataLoaders'
@ -43,8 +42,7 @@ describe('Onboarding.Components.VerifyStep.VerifyDataSwitcher', () => {
it('renders the DataStreaming component', () => {
const {wrapper} = setup({type: DataLoaderType.Streaming})
const dataStreaming = wrapper.find(DataStreaming)
expect(dataStreaming.exists()).toBe(true)
expect(wrapper).toMatchSnapshot()
})
})
})

View File

@ -1,10 +1,10 @@
// Libraries
import React, {PureComponent} from 'react'
import {connect} from 'react-redux'
// Components
import {ErrorHandling} from 'src/shared/decorators/errors'
import DataStreaming from 'src/onboarding/components/verifyStep/DataStreaming'
import FetchAuthToken from 'src/onboarding/components/verifyStep/FetchAuthToken'
// Actions
import {createOrUpdateTelegrafConfigAsync} from 'src/onboarding/actions/dataLoaders'
@ -16,37 +16,31 @@ import {StepStatus} from 'src/clockface/constants/wizard'
import {DataLoaderType} from 'src/types/v2/dataLoaders'
import {NotificationAction, RemoteDataState} from 'src/types'
import StatusIndicator from 'src/onboarding/components/verifyStep/lineProtocol/StatusIndicator'
import {AppState} from 'src/types/v2'
interface OwnProps {
interface Props {
notify: NotificationAction
type: DataLoaderType
org: string
bucket: string
username: string
stepIndex: number
authToken: string
telegrafConfigID: string
onSaveTelegrafConfig: typeof createOrUpdateTelegrafConfigAsync
onSetStepStatus: (index: number, status: StepStatus) => void
onDecrementCurrentStep: () => void
}
interface StateProps {
lpStatus: RemoteDataState
}
export type Props = OwnProps & StateProps
@ErrorHandling
export class VerifyDataSwitcher extends PureComponent<Props> {
public render() {
const {
org,
bucket,
username,
type,
stepIndex,
onSetStepStatus,
authToken,
telegrafConfigID,
onSaveTelegrafConfig,
notify,
@ -56,6 +50,8 @@ export class VerifyDataSwitcher extends PureComponent<Props> {
switch (type) {
case DataLoaderType.Streaming:
return (
<FetchAuthToken bucket={bucket} username={username}>
{authToken => (
<DataStreaming
notify={notify}
org={org}
@ -66,6 +62,8 @@ export class VerifyDataSwitcher extends PureComponent<Props> {
onSaveTelegrafConfig={onSaveTelegrafConfig}
stepIndex={stepIndex}
/>
)}
</FetchAuthToken>
)
case DataLoaderType.LineProtocol:
return (
@ -84,12 +82,4 @@ export class VerifyDataSwitcher extends PureComponent<Props> {
}
}
const mstp = ({
onboarding: {
dataLoaders: {lpStatus},
},
}: AppState): StateProps => ({
lpStatus,
})
export default connect<StateProps, {}, OwnProps>(mstp)(VerifyDataSwitcher)
export default VerifyDataSwitcher

View File

@ -0,0 +1,10 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Onboarding.Components.VerifyStep.VerifyDataSwitcher If data type is streaming renders the DataStreaming component 1`] = `
<FetchAuthToken
bucket=""
username=""
>
<Component />
</FetchAuthToken>
`;

View File

@ -15,24 +15,7 @@ import OnboardingStepSwitcher from 'src/onboarding/components/OnboardingStepSwit
// Actions
import {notify as notifyAction} from 'src/shared/actions/notifications'
import {
setSetupParams,
setStepStatus,
setupAdmin,
} from 'src/onboarding/actions/steps'
import {
setDataLoadersType,
updateTelegrafPluginConfig,
addConfigValue,
removeConfigValue,
setActiveTelegrafPlugin,
setPluginConfiguration,
createOrUpdateTelegrafConfigAsync,
addPluginBundleWithPlugins,
removePluginBundleWithPlugins,
setConfigArrayValue,
} from 'src/onboarding/actions/dataLoaders'
import {setSetupParams, setStepStatus, setupAdmin} from 'src/onboarding/actions'
// Constants
import {StepStatus} from 'src/clockface/constants/wizard'
@ -40,10 +23,8 @@ import {StepStatus} from 'src/clockface/constants/wizard'
// Types
import {Links} from 'src/types/v2/links'
import {SetupParams} from 'src/onboarding/apis'
import {DataLoadersState, DataLoaderType} from 'src/types/v2/dataLoaders'
import {Notification, NotificationFunc} from 'src/types'
import {AppState} from 'src/types/v2'
import OnboardingSideBar from 'src/onboarding/components/OnboardingSideBar'
export interface OnboardingStepProps {
links: Links
@ -77,16 +58,6 @@ interface DispatchProps {
notify: (message: Notification | NotificationFunc) => void
onSetSetupParams: typeof setSetupParams
onSetStepStatus: typeof setStepStatus
onSetDataLoadersType: typeof setDataLoadersType
onAddPluginBundle: typeof addPluginBundleWithPlugins
onRemovePluginBundle: typeof removePluginBundleWithPlugins
onUpdateTelegrafPluginConfig: typeof updateTelegrafPluginConfig
onAddConfigValue: typeof addConfigValue
onRemoveConfigValue: typeof removeConfigValue
onSetActiveTelegrafPlugin: typeof setActiveTelegrafPlugin
onSetPluginConfiguration: typeof setPluginConfiguration
onSetConfigArrayValue: typeof setConfigArrayValue
onSaveTelegrafConfig: typeof createOrUpdateTelegrafConfigAsync
onSetupAdmin: typeof setupAdmin
}
@ -94,78 +65,32 @@ interface StateProps {
links: Links
stepStatuses: StepStatus[]
setupParams: SetupParams
dataLoaders: DataLoadersState
}
type Props = OwnProps & StateProps & DispatchProps & WithRouterProps
@ErrorHandling
class OnboardingWizard extends PureComponent<Props> {
public stepTitles = [
'Welcome',
'Initial User Setup',
'Select Data Sources',
'Configure Data Sources',
'Verify',
'Complete',
]
public stepTitles = ['Welcome', 'Initial User Setup', 'Complete']
public stepSkippable = [true, false, true, true, true, true]
public stepSkippable = [true, false, false]
constructor(props: Props) {
super(props)
}
public render() {
const {
currentStepIndex,
dataLoaders,
dataLoaders: {telegrafPlugins, telegrafConfigID},
onSetDataLoadersType,
onSetActiveTelegrafPlugin,
onSetPluginConfiguration,
onUpdateTelegrafPluginConfig,
onAddConfigValue,
onRemoveConfigValue,
onSaveTelegrafConfig,
onAddPluginBundle,
onRemovePluginBundle,
setupParams,
notify,
onSetConfigArrayValue,
onSetupAdmin,
} = this.props
const {currentStepIndex, setupParams, onSetupAdmin} = this.props
return (
<WizardFullScreen>
{this.progressHeader}
<div className="wizard-contents">
<OnboardingSideBar
notify={notify}
telegrafPlugins={telegrafPlugins}
telegrafConfigID={telegrafConfigID}
onTabClick={this.handleClickSideBarTab}
title="Plugins to Configure"
visible={this.sideBarVisible}
currentStepIndex={currentStepIndex}
onNewSourceClick={this.handleNewSourceClick}
/>
<div className="wizard-step--container">
<OnboardingStepSwitcher
currentStepIndex={currentStepIndex}
onboardingStepProps={this.onboardingStepProps}
setupParams={setupParams}
dataLoaders={dataLoaders}
onSetDataLoadersType={onSetDataLoadersType}
onUpdateTelegrafPluginConfig={onUpdateTelegrafPluginConfig}
onSetActiveTelegrafPlugin={onSetActiveTelegrafPlugin}
onSetPluginConfiguration={onSetPluginConfiguration}
onAddConfigValue={onAddConfigValue}
onRemoveConfigValue={onRemoveConfigValue}
onSaveTelegrafConfig={onSaveTelegrafConfig}
onAddPluginBundle={onAddPluginBundle}
onRemovePluginBundle={onRemovePluginBundle}
onSetConfigArrayValue={onSetConfigArrayValue}
onSetupAdmin={onSetupAdmin}
/>
</div>
@ -194,45 +119,6 @@ class OnboardingWizard extends PureComponent<Props> {
)
}
private get sideBarVisible() {
const {currentStepIndex, dataLoaders} = this.props
const {telegrafPlugins, type} = dataLoaders
const isStreaming = type === DataLoaderType.Streaming
const isNotEmpty = telegrafPlugins.length > 0
const isSideBarStep =
(currentStepIndex === 2 && isNotEmpty) ||
currentStepIndex === 3 ||
currentStepIndex === 4
return isStreaming && isSideBarStep
}
private handleNewSourceClick = () => {
const {onSetSubstepIndex, onSetActiveTelegrafPlugin} = this.props
onSetActiveTelegrafPlugin('')
onSetSubstepIndex(2, 'streaming')
}
private handleClickSideBarTab = (telegrafPluginID: string) => {
const {
onSetSubstepIndex,
onSetActiveTelegrafPlugin,
dataLoaders: {telegrafPlugins},
} = this.props
const index = Math.max(
_.findIndex(telegrafPlugins, plugin => {
return plugin.name === telegrafPluginID
}),
0
)
onSetSubstepIndex(3, index)
onSetActiveTelegrafPlugin(telegrafPluginID)
}
private handleExit = () => {
const {router, onCompleteSetup} = this.props
onCompleteSetup()
@ -276,31 +162,17 @@ class OnboardingWizard extends PureComponent<Props> {
const mstp = ({
links,
onboarding: {
steps: {stepStatuses, setupParams},
dataLoaders,
},
onboarding: {stepStatuses, setupParams},
}: AppState): StateProps => ({
links,
stepStatuses,
setupParams,
dataLoaders,
})
const mdtp: DispatchProps = {
notify: notifyAction,
onSetSetupParams: setSetupParams,
onSetStepStatus: setStepStatus,
onSetDataLoadersType: setDataLoadersType,
onUpdateTelegrafPluginConfig: updateTelegrafPluginConfig,
onAddConfigValue: addConfigValue,
onRemoveConfigValue: removeConfigValue,
onSetActiveTelegrafPlugin: setActiveTelegrafPlugin,
onSaveTelegrafConfig: createOrUpdateTelegrafConfigAsync,
onAddPluginBundle: addPluginBundleWithPlugins,
onRemovePluginBundle: removePluginBundleWithPlugins,
onSetPluginConfiguration: setPluginConfiguration,
onSetConfigArrayValue: setConfigArrayValue,
onSetupAdmin: setupAdmin,
}

View File

@ -1,6 +1,5 @@
// Reducer
import dataLoadersReducer, {
// DataLoadersState,
INITIAL_STATE,
} from 'src/onboarding/reducers/dataLoaders'
@ -462,12 +461,13 @@ describe('dataLoader reducer', () => {
const bucket = 'defbuck'
const telegrafPlugins = [cpuTelegrafPlugin]
const getState = (): any => ({
onboarding: {
dataLoading: {
dataLoaders: {
telegrafPlugins,
},
steps: {
setupParams: {org, bucket},
org,
bucket,
},
},
})

View File

@ -39,6 +39,8 @@ export const INITIAL_STATE: DataLoadersState = {
export default (state = INITIAL_STATE, action: Action): DataLoadersState => {
switch (action.type) {
case 'CLEAR_DATA_LOADERS':
return {...INITIAL_STATE}
case 'SET_DATA_LOADERS_TYPE':
return {
...state,

View File

@ -1,17 +1,37 @@
// Libraries
import {combineReducers} from 'redux'
// Constants
import {StepStatus} from 'src/clockface/constants/wizard'
// Reducers
import dataLoadersReducer from 'src/onboarding/reducers/dataLoaders'
import {DataLoadersState} from 'src/types/v2/dataLoaders'
import stepsReducer, {OnboardingStepsState} from 'src/onboarding/reducers/steps'
// Types
import {Action} from 'src/onboarding/actions'
import {SetupParams} from 'src/onboarding/apis'
export interface OnboardingState {
steps: OnboardingStepsState
dataLoaders: DataLoadersState
stepStatuses: StepStatus[]
setupParams: SetupParams
orgID: string
bucketID: string
}
export default combineReducers<OnboardingState>({
steps: stepsReducer,
dataLoaders: dataLoadersReducer,
})
const INITIAL_STATE: OnboardingState = {
stepStatuses: new Array(3).fill(StepStatus.Incomplete),
setupParams: null,
orgID: '',
bucketID: '',
}
export default (state = INITIAL_STATE, action: Action): OnboardingState => {
switch (action.type) {
case 'SET_SETUP_PARAMS':
return {...state, setupParams: action.payload.setupParams}
case 'SET_STEP_STATUS':
const stepStatuses = [...state.stepStatuses]
stepStatuses[action.payload.index] = action.payload.status
return {...state, stepStatuses}
case 'SET_ORG_ID':
return {...state, orgID: action.payload.orgID}
case 'SET_BUCKET_ID':
return {...state, bucketID: action.payload.bucketID}
default:
return state
}
}

View File

@ -3,35 +3,52 @@ import {StepStatus} from 'src/clockface/constants/wizard'
// Types
import {Action} from 'src/onboarding/actions/steps'
import {SetupParams} from 'src/onboarding/apis'
import {Substep} from 'src/types/v2/dataLoaders'
export interface OnboardingStepsState {
export interface DataLoadersStepsState {
currentStep: number
substep?: Substep
stepStatuses: StepStatus[]
setupParams: SetupParams
orgID: string
bucketID: string
org: string
bucket: string
}
const INITIAL_STATE: OnboardingStepsState = {
stepStatuses: new Array(6).fill(StepStatus.Incomplete),
setupParams: null,
const INITIAL_STATE: DataLoadersStepsState = {
stepStatuses: new Array(3).fill(StepStatus.Incomplete),
org: '',
bucket: '',
orgID: '',
bucketID: '',
currentStep: 0,
}
export default (
state = INITIAL_STATE,
action: Action
): OnboardingStepsState => {
): DataLoadersStepsState => {
switch (action.type) {
case 'SET_SETUP_PARAMS':
return {...state, setupParams: action.payload.setupParams}
case 'CLEAR_STEPS':
return {...INITIAL_STATE}
case 'INCREMENT_CURRENT_STEP_INDEX':
return {...state, currentStep: state.currentStep + 1}
case 'DECREMENT_CURRENT_STEP_INDEX':
return {...state, currentStep: state.currentStep - 1}
case 'SET_CURRENT_STEP_INDEX':
return {...state, currentStep: action.payload.index}
case 'SET_SUBSTEP_INDEX':
return {
...state,
currentStep: action.payload.stepIndex,
substep: action.payload.substep,
}
case 'SET_BUCKET_INFO':
return {...state, ...action.payload}
case 'SET_STEP_STATUS':
const stepStatuses = [...state.stepStatuses]
stepStatuses[action.payload.index] = action.payload.status
return {...state, stepStatuses}
case 'SET_ORG_ID':
return {...state, orgID: action.payload.orgID}
case 'SET_BUCKET_ID':
return {...state, bucketID: action.payload.bucketID}
default:

View File

@ -8,6 +8,7 @@ import {OverlayTechnology, IndexList} from 'src/clockface'
// Types
import {OverlayState} from 'src/types/v2'
import DataLoadersWizard from 'src/dataLoaders/components/DataLoadersWizard'
interface Props {
buckets: PrettyBucket[]
@ -18,7 +19,8 @@ interface Props {
interface State {
bucketID: string
overlayState: OverlayState
bucketOverlayState: OverlayState
dataLoadersOverlayState: OverlayState
}
export default class BucketList extends PureComponent<Props, State> {
@ -27,7 +29,8 @@ export default class BucketList extends PureComponent<Props, State> {
this.state = {
bucketID: null,
overlayState: OverlayState.Closed,
bucketOverlayState: OverlayState.Closed,
dataLoadersOverlayState: OverlayState.Closed,
}
}
@ -49,17 +52,23 @@ export default class BucketList extends PureComponent<Props, State> {
bucket={bucket}
onEditBucket={this.handleStartEdit}
onDeleteBucket={onDeleteBucket}
onAddData={this.handleStartAddData}
/>
))}
</IndexList.Body>
</IndexList>
<OverlayTechnology visible={this.isOverlayVisible}>
<OverlayTechnology visible={this.isBucketOverlayVisible}>
<UpdateBucketOverlay
bucket={this.bucket}
onCloseModal={this.handleCloseModal}
onUpdateBucket={this.handleUpdateBucket}
/>
</OverlayTechnology>
<DataLoadersWizard
visible={this.isDataLoadersWizardVisible}
onCompleteSetup={this.handleDismissDataLoaders}
bucket={this.bucket}
/>
</>
)
}
@ -69,20 +78,39 @@ export default class BucketList extends PureComponent<Props, State> {
}
private handleCloseModal = () => {
this.setState({overlayState: OverlayState.Closed})
this.setState({bucketOverlayState: OverlayState.Closed})
}
private handleStartEdit = (bucket: PrettyBucket) => {
this.setState({bucketID: bucket.id, overlayState: OverlayState.Open})
this.setState({bucketID: bucket.id, bucketOverlayState: OverlayState.Open})
}
private get isOverlayVisible(): boolean {
const {bucketID, overlayState} = this.state
return !!bucketID && overlayState === OverlayState.Open
private handleStartAddData = (bucket: PrettyBucket) => {
this.setState({
bucketID: bucket.id,
dataLoadersOverlayState: OverlayState.Open,
})
}
private handleDismissDataLoaders = () => {
this.setState({
bucketID: '',
dataLoadersOverlayState: OverlayState.Closed,
})
}
private get isDataLoadersWizardVisible(): boolean {
const {bucketID, dataLoadersOverlayState} = this.state
return !!bucketID && dataLoadersOverlayState === OverlayState.Open
}
private get isBucketOverlayVisible(): boolean {
const {bucketID, bucketOverlayState} = this.state
return !!bucketID && bucketOverlayState === OverlayState.Open
}
private handleUpdateBucket = async (updatedBucket: PrettyBucket) => {
await this.props.onUpdateBucket(updatedBucket)
this.setState({overlayState: OverlayState.Closed})
this.setState({bucketOverlayState: OverlayState.Closed})
}
}

View File

@ -7,10 +7,12 @@ import {
IndexList,
ConfirmationButton,
Alignment,
Button,
ComponentSpacer,
ComponentColor,
} from 'src/clockface'
// Types
import {OverlayState} from 'src/types/v2'
import {Bucket} from 'src/api'
export interface PrettyBucket extends Bucket {
@ -21,13 +23,10 @@ interface Props {
bucket: PrettyBucket
onEditBucket: (b: PrettyBucket) => void
onDeleteBucket: (b: PrettyBucket) => void
onAddData: (b: PrettyBucket) => void
}
interface State {
overlayState: OverlayState
}
export default class BucketRow extends PureComponent<Props, State> {
export default class BucketRow extends PureComponent<Props> {
public render() {
const {bucket, onDeleteBucket} = this.props
return (
@ -40,6 +39,12 @@ export default class BucketRow extends PureComponent<Props, State> {
</IndexList.Cell>
<IndexList.Cell>{bucket.ruleString}</IndexList.Cell>
<IndexList.Cell revealOnHover={true} alignment={Alignment.Right}>
<ComponentSpacer align={Alignment.Right}>
<Button
text={'Add Data'}
onClick={this.handleClickAddData}
color={ComponentColor.Default}
/>
<ConfirmationButton
size={ComponentSize.ExtraSmall}
text="Delete"
@ -47,6 +52,7 @@ export default class BucketRow extends PureComponent<Props, State> {
onConfirm={onDeleteBucket}
returnValue={bucket}
/>
</ComponentSpacer>
</IndexList.Cell>
</IndexList.Row>
</>
@ -56,4 +62,8 @@ export default class BucketRow extends PureComponent<Props, State> {
private handleEditBucket = (): void => {
this.props.onEditBucket(this.props.bucket)
}
private handleClickAddData = (): void => {
this.props.onAddData(this.props.bucket)
}
}

View File

@ -19,8 +19,9 @@ import viewsReducer from 'src/dashboards/reducers/v2/views'
import logsReducer from 'src/logs/reducers'
import {timeMachinesReducer} from 'src/shared/reducers/v2/timeMachines'
import orgsReducer from 'src/organizations/reducers/orgs'
import onboardingReducer from 'src/onboarding/reducers/'
import onboardingReducer from 'src/onboarding/reducers'
import noteEditorReducer from 'src/dashboards/reducers/v2/notes'
import dataLoadingReducer from 'src/dataLoaders/reducers'
// Types
import {LocalStorage} from 'src/types/localStorage'
@ -45,6 +46,7 @@ const rootReducer = combineReducers<ReducerState>({
me: meReducer,
onboarding: onboardingReducer,
noteEditor: noteEditorReducer,
dataLoading: dataLoadingReducer,
})
const composeEnhancers =

View File

@ -185,3 +185,5 @@ export interface TelegrafPluginInfo {
defaults: Plugin
}
}
export type Substep = number | 'streaming'

View File

@ -34,8 +34,9 @@ import {RouterState} from 'react-router-redux'
import {MeState} from 'src/shared/reducers/v2/me'
import {OverlayState} from 'src/types/v2/overlay'
import {SourcesState} from 'src/sources/reducers'
import {OnboardingState} from 'src/onboarding/reducers'
import {NoteEditorState} from 'src/dashboards/reducers/v2/notes'
import {DataLoadingState} from 'src/dataLoaders/reducers'
import {OnboardingState} from 'src/onboarding/reducers'
export interface AppState {
VERSION: string
@ -55,6 +56,7 @@ export interface AppState {
me: MeState
onboarding: OnboardingState
noteEditor: NoteEditorState
dataLoading: DataLoadingState
}
export type GetState = () => AppState