From 4918d7ae67bdd077c694b9b223adf6b8fc2aae4f Mon Sep 17 00:00:00 2001 From: Iris Scholten Date: Tue, 15 Jan 2019 11:58:10 -0800 Subject: [PATCH] Move dataloading into admin ui Co-authored-by: Daniel Campbell --- http/cur_swagger.yml | 2 +- http/swagger.yml | 2 +- ui/src/api/api.ts | 2 +- .../components/wizard/ProgressBar.scss | 14 + .../components/wizard/ProgressBar.tsx | 10 +- .../components/wizard/WizardOverlay.scss | 9 + .../components/wizard/WizardOverlay.tsx | 11 +- ui/src/clockface/index.ts | 2 + ui/src/clockface/styles.scss | 1 + .../components/DataLoadersWizard.tsx | 335 ++++++++++++++++++ .../dataLoaders/components/StepSwitcher.tsx | 119 +++++++ ui/src/dataLoaders/reducers/index.tsx | 19 + ui/src/logs/utils/logQuery.test.ts | 2 +- ui/src/logs/utils/v1/queryBuilder.test.ts | 2 +- ui/src/logs/utils/v2/queryBuilder.test.ts | 2 +- ui/src/onboarding/actions/dataLoaders.ts | 20 +- ui/src/onboarding/actions/index.ts | 87 +++++ ui/src/onboarding/actions/steps.ts | 117 +++--- ui/src/onboarding/components/AdminStep.tsx | 21 +- .../components/OnboardingStepSwitcher.tsx | 102 +----- ...deBar.test.tsx => PluginsSideBar.test.tsx} | 6 +- ...boardingSideBar.tsx => PluginsSideBar.tsx} | 4 +- .../__snapshots__/AdminStep.test.tsx.snap | 18 +- ....tsx.snap => PluginsSideBar.test.tsx.snap} | 2 +- .../ConfigureDataSourceStep.test.tsx | 9 +- .../configureStep/ConfigureDataSourceStep.tsx | 87 +++-- .../components/configureStep/Scraping.tsx | 27 +- .../lineProtocol/LineProtocol.tsx | 2 +- .../lineProtocol/LineProtocolTabs.tsx | 2 +- .../SelectDataSourceStep.test.tsx | 12 +- .../selectionStep/SelectDataSourceStep.tsx | 43 +-- .../verifyStep/VerifyDataStep.test.tsx | 14 +- .../components/verifyStep/VerifyDataStep.tsx | 55 ++- .../verifyStep/VerifyDataSwitcher.test.tsx | 4 +- .../verifyStep/VerifyDataSwitcher.tsx | 48 +-- .../VerifyDataSwitcher.test.tsx.snap | 10 + .../containers/OnboardingWizard.tsx | 138 +------- .../onboarding/reducers/dataLoaders.test.ts | 6 +- ui/src/onboarding/reducers/dataLoaders.ts | 2 + ui/src/onboarding/reducers/index.ts | 44 ++- ui/src/onboarding/reducers/steps.ts | 39 +- .../organizations/components/BucketList.tsx | 46 ++- ui/src/organizations/components/BucketRow.tsx | 36 +- ui/src/store/configureStore.ts | 4 +- ui/src/types/v2/dataLoaders.ts | 2 + ui/src/types/v2/index.ts | 4 +- 46 files changed, 1000 insertions(+), 543 deletions(-) create mode 100644 ui/src/clockface/components/wizard/WizardOverlay.scss create mode 100644 ui/src/dataLoaders/components/DataLoadersWizard.tsx create mode 100644 ui/src/dataLoaders/components/StepSwitcher.tsx create mode 100644 ui/src/dataLoaders/reducers/index.tsx create mode 100644 ui/src/onboarding/actions/index.ts rename ui/src/onboarding/components/{OnboardingSideBar.test.tsx => PluginsSideBar.test.tsx} (92%) rename ui/src/onboarding/components/{OnboardingSideBar.tsx => PluginsSideBar.tsx} (97%) rename ui/src/onboarding/components/__snapshots__/{OnboardingSideBar.test.tsx.snap => PluginsSideBar.test.tsx.snap} (90%) create mode 100644 ui/src/onboarding/components/verifyStep/__snapshots__/VerifyDataSwitcher.test.tsx.snap diff --git a/http/cur_swagger.yml b/http/cur_swagger.yml index 9bcae0bf9b..3c3268cb48 100644 --- a/http/cur_swagger.yml +++ b/http/cur_swagger.yml @@ -4168,7 +4168,7 @@ components: type: string rp: type: string - orgID: + organizationID: type: string retentionRules: type: array diff --git a/http/swagger.yml b/http/swagger.yml index 965dc0ada8..ccc4defd6b 100644 --- a/http/swagger.yml +++ b/http/swagger.yml @@ -4985,7 +4985,7 @@ components: type: string name: type: string - orgID: + organizationID: type: string organization: type: string diff --git a/ui/src/api/api.ts b/ui/src/api/api.ts index f8d9d3663c..a25a371f69 100644 --- a/ui/src/api/api.ts +++ b/ui/src/api/api.ts @@ -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} diff --git a/ui/src/clockface/components/wizard/ProgressBar.scss b/ui/src/clockface/components/wizard/ProgressBar.scss index 12fd506d12..0100b29451 100644 --- a/ui/src/clockface/components/wizard/ProgressBar.scss +++ b/ui/src/clockface/components/wizard/ProgressBar.scss @@ -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; diff --git a/ui/src/clockface/components/wizard/ProgressBar.tsx b/ui/src/clockface/components/wizard/ProgressBar.tsx index 3566154f0b..f5aeaeee02 100644 --- a/ui/src/clockface/components/wizard/ProgressBar.tsx +++ b/ui/src/clockface/components/wizard/ProgressBar.tsx @@ -14,6 +14,7 @@ interface Props { stepStatuses: StepStatus[] stepTitles: string[] stepSkippable: boolean[] + hideFirstStep?: boolean } @ErrorHandling @@ -68,13 +69,18 @@ class ProgressBar extends PureComponent { } 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] } diff --git a/ui/src/clockface/components/wizard/WizardOverlay.scss b/ui/src/clockface/components/wizard/WizardOverlay.scss new file mode 100644 index 0000000000..5bace8589b --- /dev/null +++ b/ui/src/clockface/components/wizard/WizardOverlay.scss @@ -0,0 +1,9 @@ +/* + Wizard Overlay Styles +*/ + +.wizard-overlay { + >.wizard-contents { + margin: 0; + } +} \ No newline at end of file diff --git a/ui/src/clockface/components/wizard/WizardOverlay.tsx b/ui/src/clockface/components/wizard/WizardOverlay.tsx index 301d5bfa66..6f9725de06 100644 --- a/ui/src/clockface/components/wizard/WizardOverlay.tsx +++ b/ui/src/clockface/components/wizard/WizardOverlay.tsx @@ -19,22 +19,25 @@ interface Props { resetWizardState: () => void maxWidth?: number jumpStep: number + onDismis: () => void } @ErrorHandling class WizardOverlay extends PureComponent { public static defaultProps: Partial = { - maxWidth: 800, + maxWidth: 1200, } public render() { - const {visible, title, maxWidth} = this.props + const {visible, title, maxWidth, children, onDismis} = this.props return ( - - wizard + + +
{children}
+
) diff --git a/ui/src/clockface/index.ts b/ui/src/clockface/index.ts index c3238ea8df..3bed3adf07 100644 --- a/ui/src/clockface/index.ts +++ b/ui/src/clockface/index.ts @@ -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, } diff --git a/ui/src/clockface/styles.scss b/ui/src/clockface/styles.scss index bce89915ec..b6487527f6 100644 --- a/ui/src/clockface/styles.scss +++ b/ui/src/clockface/styles.scss @@ -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'; \ No newline at end of file diff --git a/ui/src/dataLoaders/components/DataLoadersWizard.tsx b/ui/src/dataLoaders/components/DataLoadersWizard.tsx new file mode 100644 index 0000000000..f618d5d71b --- /dev/null +++ b/ui/src/dataLoaders/components/DataLoadersWizard.tsx @@ -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 { + 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 ( + + {this.progressHeader} +
+ +
+ +
+
+
+ ) + } + + private handleDismiss = () => { + this.props.onClearDataLoaders() + this.props.onClearSteps() + this.props.onCompleteSetup() + } + + private get progressHeader(): JSX.Element { + const {stepStatuses, currentStepIndex, onSetCurrentStepIndex} = this.props + + return ( + + + + ) + } + + 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( + mstp, + mdtp +)(DataLoadersWizard) diff --git a/ui/src/dataLoaders/components/StepSwitcher.tsx b/ui/src/dataLoaders/components/StepSwitcher.tsx new file mode 100644 index 0000000000..212f685b84 --- /dev/null +++ b/ui/src/dataLoaders/components/StepSwitcher.tsx @@ -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 { + 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 ( + + ) + case 1: + return ( + + ) + case 2: + return ( + + ) + default: + return
+ } + } +} + +export default StepSwitcher diff --git a/ui/src/dataLoaders/reducers/index.tsx b/ui/src/dataLoaders/reducers/index.tsx new file mode 100644 index 0000000000..a12c083363 --- /dev/null +++ b/ui/src/dataLoaders/reducers/index.tsx @@ -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({ + steps: stepsReducer, + dataLoaders: dataLoadersReducer, +}) diff --git a/ui/src/logs/utils/logQuery.test.ts b/ui/src/logs/utils/logQuery.test.ts index 572d0a80d2..879ab62b18 100644 --- a/ui/src/logs/utils/logQuery.test.ts +++ b/ui/src/logs/utils/logQuery.test.ts @@ -22,7 +22,7 @@ describe('Logs.LogQuery', () => { config = buildTableQueryConfig({ id: '1', organization: 'default', - orgID: '1', + organizationID: '1', name: 'telegraf', rp: 'autogen', retentionRules: [], diff --git a/ui/src/logs/utils/v1/queryBuilder.test.ts b/ui/src/logs/utils/v1/queryBuilder.test.ts index 500e1ccaa1..130b57c741 100644 --- a/ui/src/logs/utils/v1/queryBuilder.test.ts +++ b/ui/src/logs/utils/v1/queryBuilder.test.ts @@ -15,7 +15,7 @@ describe('Logs.V1.queryBuilder', () => { config = buildTableQueryConfig({ id: '1', organization: 'default', - orgID: '1', + organizationID: '1', name: 'telegraf', rp: 'autogen', retentionRules: [], diff --git a/ui/src/logs/utils/v2/queryBuilder.test.ts b/ui/src/logs/utils/v2/queryBuilder.test.ts index a9733c85d1..40c37ca834 100644 --- a/ui/src/logs/utils/v2/queryBuilder.test.ts +++ b/ui/src/logs/utils/v2/queryBuilder.test.ts @@ -15,7 +15,7 @@ describe('Logs.V2.queryBuilder', () => { config = buildTableQueryConfig({ id: '1', organization: 'default', - orgID: '1', + organizationID: '1', name: 'telegraf', rp: 'autogen', retentionRules: [], diff --git a/ui/src/onboarding/actions/dataLoaders.ts b/ui/src/onboarding/actions/dataLoaders.ts index 0532934fd0..bc0eeec920 100644 --- a/ui/src/onboarding/actions/dataLoaders.ts +++ b/ui/src/onboarding/actions/dataLoaders.ts @@ -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() diff --git a/ui/src/onboarding/actions/index.ts b/ui/src/onboarding/actions/index.ts new file mode 100644 index 0000000000..14fbce6adb --- /dev/null +++ b/ui/src/onboarding/actions/index.ts @@ -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)) + } +} diff --git a/ui/src/onboarding/actions/steps.ts b/ui/src/onboarding/actions/steps.ts index 14fbce6adb..25ee409478 100644 --- a/ui/src/onboarding/actions/steps.ts +++ b/ui/src/onboarding/actions/steps.ts @@ -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)) - } -} diff --git a/ui/src/onboarding/components/AdminStep.tsx b/ui/src/onboarding/components/AdminStep.tsx index 74fe963ad2..95a66a4ae3 100644 --- a/ui/src/onboarding/components/AdminStep.tsx +++ b/ui/src/onboarding/components/AdminStep.tsx @@ -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 { 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, } } diff --git a/ui/src/onboarding/components/OnboardingStepSwitcher.tsx b/ui/src/onboarding/components/OnboardingStepSwitcher.tsx index 4d9a391ee8..18d1f68f97 100644 --- a/ui/src/onboarding/components/OnboardingStepSwitcher.tsx +++ b/ui/src/onboarding/components/OnboardingStepSwitcher.tsx @@ -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 { 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 { ) case 2: - return ( - - ) - case 3: - return ( - - {authToken => ( - - )} - - ) - case 4: - return ( - - {authToken => ( - - )} - - ) - case 5: return default: return
diff --git a/ui/src/onboarding/components/OnboardingSideBar.test.tsx b/ui/src/onboarding/components/PluginsSideBar.test.tsx similarity index 92% rename from ui/src/onboarding/components/OnboardingSideBar.test.tsx rename to ui/src/onboarding/components/PluginsSideBar.test.tsx index 35ddae77da..2e9b8116ee 100644 --- a/ui/src/onboarding/components/OnboardingSideBar.test.tsx +++ b/ui/src/onboarding/components/PluginsSideBar.test.tsx @@ -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() + const wrapper = shallow() return {wrapper} } -describe('OnboardingSideBar', () => { +describe('PluginsSideBar', () => { describe('rendering', () => { it('renders! wee!', () => { const {wrapper} = setup({ diff --git a/ui/src/onboarding/components/OnboardingSideBar.tsx b/ui/src/onboarding/components/PluginsSideBar.tsx similarity index 97% rename from ui/src/onboarding/components/OnboardingSideBar.tsx rename to ui/src/onboarding/components/PluginsSideBar.tsx index 96e95e43c9..a23c0242bc 100644 --- a/ui/src/onboarding/components/OnboardingSideBar.tsx +++ b/ui/src/onboarding/components/PluginsSideBar.tsx @@ -41,7 +41,7 @@ const configStateToTabStatus = (cs: ConfigurationState): TabStatus => { } } -class OnboardingSideBar extends Component { +class PluginsSideBar extends Component { public render() { const {title, visible} = this.props return ( @@ -122,4 +122,4 @@ class OnboardingSideBar extends Component { } } -export default OnboardingSideBar +export default PluginsSideBar diff --git a/ui/src/onboarding/components/__snapshots__/AdminStep.test.tsx.snap b/ui/src/onboarding/components/__snapshots__/AdminStep.test.tsx.snap index 598fc987ea..633527e3dd 100644 --- a/ui/src/onboarding/components/__snapshots__/AdminStep.test.tsx.snap +++ b/ui/src/onboarding/components/__snapshots__/AdminStep.test.tsx.snap @@ -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="" /> diff --git a/ui/src/onboarding/components/__snapshots__/OnboardingSideBar.test.tsx.snap b/ui/src/onboarding/components/__snapshots__/PluginsSideBar.test.tsx.snap similarity index 90% rename from ui/src/onboarding/components/__snapshots__/OnboardingSideBar.test.tsx.snap rename to ui/src/onboarding/components/__snapshots__/PluginsSideBar.test.tsx.snap index ca3ca598be..bb299dbeb0 100644 --- a/ui/src/onboarding/components/__snapshots__/OnboardingSideBar.test.tsx.snap +++ b/ui/src/onboarding/components/__snapshots__/PluginsSideBar.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`OnboardingSideBar rendering renders! wee! 1`] = ` +exports[`PluginsSideBar rendering renders! wee! 1`] = ` { 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, } diff --git a/ui/src/onboarding/components/configureStep/ConfigureDataSourceStep.tsx b/ui/src/onboarding/components/configureStep/ConfigureDataSourceStep.tsx index 56f6ff4559..1ec49d2271 100644 --- a/ui/src/onboarding/components/configureStep/ConfigureDataSourceStep.tsx +++ b/ui/src/onboarding/components/configureStep/ConfigureDataSourceStep.tsx @@ -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 { @@ -55,41 +49,32 @@ export class ConfigureDataSourceStep extends PureComponent { 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 (
{ 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 (index >= telegrafPlugins.length - 1) { - onIncrementCurrentStepIndex() - onSetActiveTelegrafPlugin('') - } else { - const name = _.get(telegrafPlugins, `${index + 1}.name`, '') - onSetActiveTelegrafPlugin(name) - onSetSubstepIndex(+stepID, index + 1) + 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 } + + 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 { 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 { type, telegrafPlugins, onSetStepStatus, - params: {stepID}, + currentStepIndex, } = this.props if (type === DataLoaderType.Streaming) { @@ -184,14 +177,14 @@ export class ConfigureDataSourceStep extends PureComponent { }) 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(ConfigureDataSourceStep) +export default ConfigureDataSourceStep diff --git a/ui/src/onboarding/components/configureStep/Scraping.tsx b/ui/src/onboarding/components/configureStep/Scraping.tsx index 10204fa8a6..62ac0cb6b4 100644 --- a/ui/src/onboarding/components/configureStep/Scraping.tsx +++ b/ui/src/onboarding/components/configureStep/Scraping.tsx @@ -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 { 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 { } 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 { } 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 = { diff --git a/ui/src/onboarding/components/configureStep/lineProtocol/LineProtocol.tsx b/ui/src/onboarding/components/configureStep/lineProtocol/LineProtocol.tsx index 965746e91a..0483eaac17 100644 --- a/ui/src/onboarding/components/configureStep/lineProtocol/LineProtocol.tsx +++ b/ui/src/onboarding/components/configureStep/lineProtocol/LineProtocol.tsx @@ -108,7 +108,7 @@ export class LineProtocol extends PureComponent { } const mstp = ({ - onboarding: { + dataLoading: { dataLoaders: {lineProtocolBody, precision}, }, }: AppState): StateProps => { diff --git a/ui/src/onboarding/components/configureStep/lineProtocol/LineProtocolTabs.tsx b/ui/src/onboarding/components/configureStep/lineProtocol/LineProtocolTabs.tsx index 340972aa6e..dd72e70622 100644 --- a/ui/src/onboarding/components/configureStep/lineProtocol/LineProtocolTabs.tsx +++ b/ui/src/onboarding/components/configureStep/lineProtocol/LineProtocolTabs.tsx @@ -130,7 +130,7 @@ export class LineProtocolTabs extends PureComponent { } const mstp = ({ - onboarding: { + dataLoading: { dataLoaders: {lineProtocolBody, activeLPTab, precision}, }, }: AppState) => { diff --git a/ui/src/onboarding/components/selectionStep/SelectDataSourceStep.test.tsx b/ui/src/onboarding/components/selectionStep/SelectDataSourceStep.test.tsx index 5221f1fc41..580c791868 100644 --- a/ui/src/onboarding/components/selectionStep/SelectDataSourceStep.test.tsx +++ b/ui/src/onboarding/components/selectionStep/SelectDataSourceStep.test.tsx @@ -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) diff --git a/ui/src/onboarding/components/selectionStep/SelectDataSourceStep.tsx b/ui/src/onboarding/components/selectionStep/SelectDataSourceStep.tsx index 0fb2d4269f..0b5c1bdb7a 100644 --- a/ui/src/onboarding/components/selectionStep/SelectDataSourceStep.tsx +++ b/ui/src/onboarding/components/selectionStep/SelectDataSourceStep.tsx @@ -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 { 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 { } 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 { } } -export default withRouter(SelectDataSourceStep) +export default SelectDataSourceStep diff --git a/ui/src/onboarding/components/verifyStep/VerifyDataStep.test.tsx b/ui/src/onboarding/components/verifyStep/VerifyDataStep.test.tsx index c50ee6b543..67ef028e68 100644 --- a/ui/src/onboarding/components/verifyStep/VerifyDataStep.test.tsx +++ b/ui/src/onboarding/components/verifyStep/VerifyDataStep.test.tsx @@ -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, } diff --git a/ui/src/onboarding/components/verifyStep/VerifyDataStep.tsx b/ui/src/onboarding/components/verifyStep/VerifyDataStep.tsx index 77eaf131c9..3c60c0e7ac 100644 --- a/ui/src/onboarding/components/verifyStep/VerifyDataStep.tsx +++ b/ui/src/onboarding/components/verifyStep/VerifyDataStep.tsx @@ -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 { @@ -64,15 +58,17 @@ export class VerifyDataStep extends PureComponent { 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 { 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} />
@@ -101,6 +98,7 @@ export class VerifyDataStep extends PureComponent { onClickSkip={this.jumpToCompletionStep} skipButtonText={'Skip'} showSkip={true} + nextButtonText={'Finish'} />
@@ -118,26 +116,19 @@ export class VerifyDataStep extends PureComponent { } 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 { } const mstp = ({ - onboarding: { + dataLoading: { dataLoaders: {lpStatus}, }, }: AppState): StateProps => ({ lpStatus, }) -export default withRouter( - connect(mstp)(VerifyDataStep) -) +export default connect(mstp)(VerifyDataStep) diff --git a/ui/src/onboarding/components/verifyStep/VerifyDataSwitcher.test.tsx b/ui/src/onboarding/components/verifyStep/VerifyDataSwitcher.test.tsx index dbacab7852..a43e7a0a2a 100644 --- a/ui/src/onboarding/components/verifyStep/VerifyDataSwitcher.test.tsx +++ b/ui/src/onboarding/components/verifyStep/VerifyDataSwitcher.test.tsx @@ -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() }) }) }) diff --git a/ui/src/onboarding/components/verifyStep/VerifyDataSwitcher.tsx b/ui/src/onboarding/components/verifyStep/VerifyDataSwitcher.tsx index 87601eef7e..89e5708431 100644 --- a/ui/src/onboarding/components/verifyStep/VerifyDataSwitcher.tsx +++ b/ui/src/onboarding/components/verifyStep/VerifyDataSwitcher.tsx @@ -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 { public render() { const { org, bucket, + username, type, stepIndex, onSetStepStatus, - authToken, telegrafConfigID, onSaveTelegrafConfig, notify, @@ -56,16 +50,20 @@ export class VerifyDataSwitcher extends PureComponent { switch (type) { case DataLoaderType.Streaming: return ( - + + {authToken => ( + + )} + ) case DataLoaderType.LineProtocol: return ( @@ -84,12 +82,4 @@ export class VerifyDataSwitcher extends PureComponent { } } -const mstp = ({ - onboarding: { - dataLoaders: {lpStatus}, - }, -}: AppState): StateProps => ({ - lpStatus, -}) - -export default connect(mstp)(VerifyDataSwitcher) +export default VerifyDataSwitcher diff --git a/ui/src/onboarding/components/verifyStep/__snapshots__/VerifyDataSwitcher.test.tsx.snap b/ui/src/onboarding/components/verifyStep/__snapshots__/VerifyDataSwitcher.test.tsx.snap new file mode 100644 index 0000000000..ff90e15754 --- /dev/null +++ b/ui/src/onboarding/components/verifyStep/__snapshots__/VerifyDataSwitcher.test.tsx.snap @@ -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`] = ` + + + +`; diff --git a/ui/src/onboarding/containers/OnboardingWizard.tsx b/ui/src/onboarding/containers/OnboardingWizard.tsx index f42fe9be55..cba99f14f8 100644 --- a/ui/src/onboarding/containers/OnboardingWizard.tsx +++ b/ui/src/onboarding/containers/OnboardingWizard.tsx @@ -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 { - 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 ( {this.progressHeader}
-
@@ -194,45 +119,6 @@ class OnboardingWizard extends PureComponent { ) } - 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 { 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, } diff --git a/ui/src/onboarding/reducers/dataLoaders.test.ts b/ui/src/onboarding/reducers/dataLoaders.test.ts index 1db7d6f6a5..d5931e1157 100644 --- a/ui/src/onboarding/reducers/dataLoaders.test.ts +++ b/ui/src/onboarding/reducers/dataLoaders.test.ts @@ -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, }, }, }) diff --git a/ui/src/onboarding/reducers/dataLoaders.ts b/ui/src/onboarding/reducers/dataLoaders.ts index 50c4cbdbc4..4e5ed94007 100644 --- a/ui/src/onboarding/reducers/dataLoaders.ts +++ b/ui/src/onboarding/reducers/dataLoaders.ts @@ -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, diff --git a/ui/src/onboarding/reducers/index.ts b/ui/src/onboarding/reducers/index.ts index 7d185256ad..ba97ae714c 100644 --- a/ui/src/onboarding/reducers/index.ts +++ b/ui/src/onboarding/reducers/index.ts @@ -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({ - 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 + } +} diff --git a/ui/src/onboarding/reducers/steps.ts b/ui/src/onboarding/reducers/steps.ts index ea593b6662..0ef55d6b46 100644 --- a/ui/src/onboarding/reducers/steps.ts +++ b/ui/src/onboarding/reducers/steps.ts @@ -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: diff --git a/ui/src/organizations/components/BucketList.tsx b/ui/src/organizations/components/BucketList.tsx index 8dc9504357..64ea578fc8 100644 --- a/ui/src/organizations/components/BucketList.tsx +++ b/ui/src/organizations/components/BucketList.tsx @@ -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 { @@ -27,7 +29,8 @@ export default class BucketList extends PureComponent { this.state = { bucketID: null, - overlayState: OverlayState.Closed, + bucketOverlayState: OverlayState.Closed, + dataLoadersOverlayState: OverlayState.Closed, } } @@ -49,17 +52,23 @@ export default class BucketList extends PureComponent { bucket={bucket} onEditBucket={this.handleStartEdit} onDeleteBucket={onDeleteBucket} + onAddData={this.handleStartAddData} /> ))} - + + ) } @@ -69,20 +78,39 @@ export default class BucketList extends PureComponent { } 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}) } } diff --git a/ui/src/organizations/components/BucketRow.tsx b/ui/src/organizations/components/BucketRow.tsx index 6a4c813a3d..f34e24d2c1 100644 --- a/ui/src/organizations/components/BucketRow.tsx +++ b/ui/src/organizations/components/BucketRow.tsx @@ -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 { +export default class BucketRow extends PureComponent { public render() { const {bucket, onDeleteBucket} = this.props return ( @@ -40,13 +39,20 @@ export default class BucketRow extends PureComponent { {bucket.ruleString} - + +