diff --git a/ui/mocks/dummyData.ts b/ui/mocks/dummyData.ts index 317cd67857..6a592f37e5 100644 --- a/ui/mocks/dummyData.ts +++ b/ui/mocks/dummyData.ts @@ -282,6 +282,7 @@ export const defaultOnboardingStepProps: OnboardingStepProps = { notify: jest.fn(), onCompleteSetup: jest.fn(), onExit: jest.fn(), + onSetSubstepIndex: jest.fn(), } export const token = diff --git a/ui/src/onboarding/components/AdminStep.test.tsx b/ui/src/onboarding/components/AdminStep.test.tsx new file mode 100644 index 0000000000..4a8744d781 --- /dev/null +++ b/ui/src/onboarding/components/AdminStep.test.tsx @@ -0,0 +1,27 @@ +// Libraries +import React from 'react' +import {shallow} from 'enzyme' + +// Components +import AdminStep from 'src/onboarding/components/AdminStep' + +// Dummy Data +import {defaultOnboardingStepProps} from 'mocks/dummyData' + +const setup = (override = {}) => { + const props = { + ...defaultOnboardingStepProps, + ...override, + } + + return shallow() +} + +describe('Onboarding.Components.AdminStep', () => { + it('renders', () => { + const wrapper = setup() + + expect(wrapper.exists()).toBe(true) + expect(wrapper).toMatchSnapshot() + }) +}) diff --git a/ui/src/onboarding/components/AdminStep.tsx b/ui/src/onboarding/components/AdminStep.tsx index 765db50262..0319afdeae 100644 --- a/ui/src/onboarding/components/AdminStep.tsx +++ b/ui/src/onboarding/components/AdminStep.tsx @@ -148,13 +148,13 @@ class AdminStep extends PureComponent {
+ +`; diff --git a/ui/src/onboarding/components/__snapshots__/CompletionStep.test.tsx.snap b/ui/src/onboarding/components/__snapshots__/CompletionStep.test.tsx.snap new file mode 100644 index 0000000000..4344950f9f --- /dev/null +++ b/ui/src/onboarding/components/__snapshots__/CompletionStep.test.tsx.snap @@ -0,0 +1,43 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Onboarding.Components.CompletionStep renders 1`] = ` +
+
+

+ Setup Complete! +

+
+
+
+
+`; diff --git a/ui/src/onboarding/components/configureStep/ConfigureDataSourceStep.test.tsx b/ui/src/onboarding/components/configureStep/ConfigureDataSourceStep.test.tsx new file mode 100644 index 0000000000..db7473dbfe --- /dev/null +++ b/ui/src/onboarding/components/configureStep/ConfigureDataSourceStep.test.tsx @@ -0,0 +1,177 @@ +// Libraries +import React from 'react' +import {shallow} from 'enzyme' + +// Components +import {ConfigureDataSourceStep} from 'src/onboarding/components/configureStep/ConfigureDataSourceStep' +import ConfigureDataSourceSwitcher from 'src/onboarding/components/configureStep/ConfigureDataSourceSwitcher' +import {Button} from 'src/clockface' + +// Types +import {DataLoaderType} from 'src/types/v2/dataLoaders' + +// Dummy Data +import { + defaultOnboardingStepProps, + cpuTelegrafPlugin, + redisTelegrafPlugin, + diskTelegrafPlugin, +} from 'mocks/dummyData' + +const setup = (override = {}) => { + const props = { + ...defaultOnboardingStepProps, + telegrafPlugins: [], + onSetActiveTelegrafPlugin: jest.fn(), + onUpdateTelegrafPluginConfig: jest.fn(), + onSetPluginConfiguration: jest.fn(), + type: DataLoaderType.Empty, + onAddConfigValue: jest.fn(), + onRemoveConfigValue: jest.fn(), + onSaveTelegrafConfig: jest.fn(), + authToken: '', + params: { + stepID: '3', + substepID: '0', + }, + location: null, + router: null, + routes: [], + ...override, + } + + return shallow() +} + +describe('Onboarding.Components.ConfigureStep.ConfigureDataSourceStep', () => { + it('renders switcher and buttons', async () => { + const wrapper = setup() + const switcher = wrapper.find(ConfigureDataSourceSwitcher) + const buttons = wrapper.find(Button) + + expect(wrapper.exists()).toBe(true) + expect(switcher.exists()).toBe(true) + expect(buttons.length).toBe(3) + }) + + describe('if type is not streaming', () => { + it('renders back and next buttons with correct text', () => { + const wrapper = setup({type: DataLoaderType.LineProtocol}) + const backButton = wrapper.find('[data-test="back"]') + const nextButton = wrapper.find('[data-test="next"]') + + expect(backButton.prop('text')).toBe('Back to Select Data Source Type') + expect(nextButton.prop('text')).toBe('Continue to Verify') + }) + }) + + describe('if type is streaming', () => { + describe('if the substep is 0', () => { + it('renders back button with correct text', () => { + const wrapper = setup({ + type: DataLoaderType.Streaming, + params: {stepID: '3', substepID: '0'}, + }) + const backButton = wrapper.find('[data-test="back"]') + + expect(backButton.prop('text')).toBe('Back to Select Streaming Sources') + }) + + describe('when the back button is clicked', () => { + it('calls prop functions as expected', () => { + const onSetActiveTelegrafPlugin = jest.fn() + const onSetSubstepIndex = jest.fn() + const wrapper = setup({ + type: DataLoaderType.Streaming, + telegrafPlugins: [cpuTelegrafPlugin], + params: {stepID: '3', substepID: '0'}, + onSetActiveTelegrafPlugin, + onSetSubstepIndex, + }) + const backButton = wrapper.find('[data-test="back"]') + backButton.simulate('click') + + expect(onSetSubstepIndex).toBeCalledWith(2, 'streaming') + }) + }) + }) + + describe('if its the last stubstep', () => { + it('renders the next button with correct text', () => { + const wrapper = setup({ + type: DataLoaderType.Streaming, + telegrafPlugins: [cpuTelegrafPlugin], + params: {stepID: '3', substepID: '1'}, + }) + const nextButton = wrapper.find('[data-test="next"]') + + expect(nextButton.prop('text')).toBe('Continue to Verify') + }) + }) + + describe('if its the neither the last or firt stubstep', () => { + it('renders the next and back buttons with correct text', () => { + const wrapper = setup({ + type: DataLoaderType.Streaming, + telegrafPlugins: [ + cpuTelegrafPlugin, + redisTelegrafPlugin, + diskTelegrafPlugin, + ], + params: {stepID: '3', substepID: '1'}, + }) + const nextButton = wrapper.find('[data-test="next"]') + const backButton = wrapper.find('[data-test="back"]') + + expect(nextButton.prop('text')).toBe('Continue to Disk') + expect(backButton.prop('text')).toBe('Back to Cpu') + }) + + describe('when the back button is clicked', () => { + it('calls prop functions as expected', () => { + const onSetActiveTelegrafPlugin = jest.fn() + const onSetSubstepIndex = jest.fn() + const wrapper = setup({ + type: DataLoaderType.Streaming, + telegrafPlugins: [ + cpuTelegrafPlugin, + redisTelegrafPlugin, + diskTelegrafPlugin, + ], + params: {stepID: '3', substepID: '1'}, + onSetActiveTelegrafPlugin, + onSetSubstepIndex, + }) + const backButton = wrapper.find('[data-test="back"]') + backButton.simulate('click') + + expect(onSetActiveTelegrafPlugin).toBeCalledWith('cpu') + expect(onSetSubstepIndex).toBeCalledWith(3, 0) + }) + }) + + describe('when the next button is clicked', () => { + it('calls prop functions as expected', () => { + const onSetActiveTelegrafPlugin = jest.fn() + const onSetSubstepIndex = jest.fn() + const wrapper = setup({ + type: DataLoaderType.Streaming, + telegrafPlugins: [ + cpuTelegrafPlugin, + redisTelegrafPlugin, + diskTelegrafPlugin, + ], + params: {stepID: '3', substepID: '1'}, + onSetActiveTelegrafPlugin, + onSetSubstepIndex, + }) + const nextButton = wrapper.find('[data-test="next"]') + nextButton.simulate('click') + + expect(onSetActiveTelegrafPlugin).toBeCalledWith('disk') + expect(onSetSubstepIndex).toBeCalledWith(3, 2) + }) + }) + }) + }) +}) diff --git a/ui/src/onboarding/components/configureStep/ConfigureDataSourceStep.tsx b/ui/src/onboarding/components/configureStep/ConfigureDataSourceStep.tsx index 3bcbddafae..16a8874cee 100644 --- a/ui/src/onboarding/components/configureStep/ConfigureDataSourceStep.tsx +++ b/ui/src/onboarding/components/configureStep/ConfigureDataSourceStep.tsx @@ -60,7 +60,7 @@ interface RouterProps { type Props = OwnProps & WithRouterProps & RouterProps @ErrorHandling -class ConfigureDataSourceStep extends PureComponent { +export class ConfigureDataSourceStep extends PureComponent { constructor(props: Props) { super(props) } @@ -108,17 +108,19 @@ class ConfigureDataSourceStep extends PureComponent {
{this.skipLink} @@ -127,6 +129,48 @@ class ConfigureDataSourceStep extends PureComponent { ) } + private get nextButtonText(): string { + const { + telegrafPlugins, + params: {substepID}, + type, + } = this.props + + const index = +substepID + + if (type === DataLoaderType.Streaming) { + if (index + 1 > telegrafPlugins.length - 1) { + return 'Continue to Verify' + } + return `Continue to ${_.startCase( + _.get(telegrafPlugins, `${index + 1}.name`) + )}` + } + + return 'Continue to Verify' + } + + private get backButtonText(): string { + const { + telegrafPlugins, + params: {substepID}, + type, + } = this.props + + const index = +substepID + + if (type === DataLoaderType.Streaming) { + if (index < 1) { + return 'Back to Select Streaming Sources' + } + return `Back to ${_.startCase( + _.get(telegrafPlugins, `${index - 1}.name`) + )}` + } + + return 'Back to Select Data Source Type' + } + private get skipLink() { return (
{this.skipLink} @@ -96,6 +98,53 @@ class SelectDataSourceStep extends PureComponent { ) } + private get nextButtonStatus(): ComponentStatus { + const {type, telegrafPlugins} = this.props + + const isTypeEmpty = type === DataLoaderType.Empty + const isStreamingWithoutPlugin = + type === DataLoaderType.Streaming && + this.isStreaming && + !telegrafPlugins.length + + if (isTypeEmpty || isStreamingWithoutPlugin) { + return ComponentStatus.Disabled + } + + return ComponentStatus.Default + } + + private get nextButtonText(): string { + const {type, telegrafPlugins} = this.props + + switch (type) { + case DataLoaderType.CSV: + return 'Continue to CSV Configuration' + case DataLoaderType.Streaming: + if (this.isStreaming) { + if (telegrafPlugins.length) { + return `Continue to ${_.startCase(telegrafPlugins[0].name)}` + } + return 'Continue to Plugin Configuration' + } + return 'Continue to Streaming Selection' + case DataLoaderType.LineProtocol: + return 'Continue to Line Protocol Configuration' + case DataLoaderType.Empty: + return 'Continue to Configuration' + } + } + + private get backButtonText(): string { + if (this.props.type === DataLoaderType.Streaming) { + if (this.isStreaming) { + return 'Back to Data Source Selection' + } + } + + return 'Back to Admin Setup' + } + private get title(): string { const {bucket} = this.props if (this.isStreaming) { @@ -145,25 +194,38 @@ class SelectDataSourceStep extends PureComponent { private handleClickNext = () => { const { - router, params: {stepID}, telegrafPlugins, onSetActiveTelegrafPlugin, + onSetSubstepIndex, } = this.props if (this.props.type === DataLoaderType.Streaming && !this.isStreaming) { - router.push(`/onboarding/${stepID}/streaming`) + onSetSubstepIndex(+stepID, 'streaming') + onSetActiveTelegrafPlugin('') return } - const name = _.get(telegrafPlugins, '0.name', '') - onSetActiveTelegrafPlugin(name) + if (this.isStreaming) { + const name = _.get(telegrafPlugins, '0.name', '') + onSetActiveTelegrafPlugin(name) + } this.handleSetStepStatus() this.props.onIncrementCurrentStepIndex() } private handleClickBack = () => { + const { + params: {stepID}, + onSetCurrentStepIndex, + } = this.props + + if (this.isStreaming) { + onSetCurrentStepIndex(+stepID) + return + } + this.props.onDecrementCurrentStepIndex() } diff --git a/ui/src/onboarding/components/verifyStep/VerifyDataStep.test.tsx b/ui/src/onboarding/components/verifyStep/VerifyDataStep.test.tsx index b00bf04030..4c2396ff97 100644 --- a/ui/src/onboarding/components/verifyStep/VerifyDataStep.test.tsx +++ b/ui/src/onboarding/components/verifyStep/VerifyDataStep.test.tsx @@ -11,12 +11,12 @@ import {Button} from 'src/clockface' import {DataLoaderType} from 'src/types/v2/dataLoaders' // Constants -import {defaultOnboardingStepProps} from 'mocks/dummyData' +import {defaultOnboardingStepProps, cpuTelegrafPlugin} from 'mocks/dummyData' const setup = (override = {}) => { const props = { - type: DataLoaderType.Empty, ...defaultOnboardingStepProps, + type: DataLoaderType.Empty, telegrafPlugins: [], stepIndex: 4, onSetActiveTelegrafPlugin: jest.fn(), @@ -38,4 +38,55 @@ describe('Onboarding.Components.VerifyStep.VerifyDataStep', () => { expect(buttons.length).toBe(3) expect(switcher.exists()).toBe(true) }) + + describe('if type is streaming', () => { + it('renders back button with correct text', () => { + const {wrapper} = setup({ + type: DataLoaderType.Streaming, + telegrafPlugins: [cpuTelegrafPlugin], + }) + const nextButton = wrapper.find('[data-test="next"]') + const backButton = wrapper.find('[data-test="back"]') + + expect(nextButton.prop('text')).toBe('Continue to Completion') + expect(backButton.prop('text')).toBe('Back to Cpu Configuration') + }) + + describe('when the back button is clicked', () => { + describe('if the type is streaming', () => { + it('calls the prop functions as expected', () => { + const onSetSubstepIndex = jest.fn() + const onSetActiveTelegrafPlugin = jest.fn() + const {wrapper} = setup({ + type: DataLoaderType.Streaming, + telegrafPlugins: [cpuTelegrafPlugin], + onSetSubstepIndex, + onSetActiveTelegrafPlugin, + }) + const backButton = wrapper.find('[data-test="back"]') + backButton.simulate('click') + + expect(onSetSubstepIndex).toBeCalledWith(3, 0) + expect(onSetActiveTelegrafPlugin).toBeCalledWith('cpu') + }) + }) + + describe('if the type is line protocol', () => { + it('calls the prop functions as expected', () => { + const onDecrementCurrentStepIndex = jest.fn() + const onSetActiveTelegrafPlugin = jest.fn() + const {wrapper} = setup({ + type: DataLoaderType.LineProtocol, + onDecrementCurrentStepIndex, + onSetActiveTelegrafPlugin, + }) + const backButton = wrapper.find('[data-test="back"]') + backButton.simulate('click') + + expect(onDecrementCurrentStepIndex).toBeCalled() + expect(onSetActiveTelegrafPlugin).toBeCalledWith('') + }) + }) + }) + }) }) diff --git a/ui/src/onboarding/components/verifyStep/VerifyDataStep.tsx b/ui/src/onboarding/components/verifyStep/VerifyDataStep.tsx index 76a5a932a2..ef41303b30 100644 --- a/ui/src/onboarding/components/verifyStep/VerifyDataStep.tsx +++ b/ui/src/onboarding/components/verifyStep/VerifyDataStep.tsx @@ -51,17 +51,19 @@ class VerifyDataStep extends PureComponent {
{this.skipLink} @@ -83,17 +85,37 @@ class VerifyDataStep extends PureComponent { ) } + private get backButtonText(): string { + return `Back to ${_.startCase(this.previousStepName) || ''} Configuration` + } + + private get previousStepName() { + const {telegrafPlugins, type} = this.props + + if (type === DataLoaderType.Streaming) { + return _.get(telegrafPlugins, `${telegrafPlugins.length - 1}.name`, '') + } + + return type + } + private handleDecrementStep = () => { const { telegrafPlugins, onSetActiveTelegrafPlugin, onDecrementCurrentStepIndex, + onSetSubstepIndex, + stepIndex, + type, } = this.props - const name = _.get(telegrafPlugins, `${telegrafPlugins.length - 1}.name`) - onSetActiveTelegrafPlugin(name) - - onDecrementCurrentStepIndex() + if (type === DataLoaderType.Streaming) { + onSetSubstepIndex(stepIndex - 1, telegrafPlugins.length - 1 || 0) + onSetActiveTelegrafPlugin(this.previousStepName) + } else { + onDecrementCurrentStepIndex() + onSetActiveTelegrafPlugin('') + } } private jumpToCompletionStep = () => { diff --git a/ui/src/onboarding/containers/OnboardingWizard.tsx b/ui/src/onboarding/containers/OnboardingWizard.tsx index cb8fa5ab0a..eb00780cc0 100644 --- a/ui/src/onboarding/containers/OnboardingWizard.tsx +++ b/ui/src/onboarding/containers/OnboardingWizard.tsx @@ -47,6 +47,7 @@ export interface OnboardingStepProps { onIncrementCurrentStepIndex: () => void onDecrementCurrentStepIndex: () => void onSetStepStatus: (index: number, status: StepStatus) => void + onSetSubstepIndex: (index: number, subStep: number | 'streaming') => void stepStatuses: StepStatus[] stepTitles: string[] setupParams: SetupParams @@ -64,10 +65,7 @@ interface OwnProps { onIncrementCurrentStepIndex: () => void onDecrementCurrentStepIndex: () => void onSetCurrentStepIndex: (stepNumber: number) => void - onSetCurrentSubStepIndex: ( - stepNumber: number, - substep: number | 'streaming' - ) => void + onSetSubstepIndex: (stepNumber: number, substep: number | 'streaming') => void } interface DispatchProps { @@ -208,13 +206,15 @@ class OnboardingWizard extends PureComponent { } private handleNewSourceClick = () => { - const {onSetCurrentSubStepIndex} = this.props - onSetCurrentSubStepIndex(2, 'streaming') + const {onSetSubstepIndex, onSetActiveTelegrafPlugin} = this.props + + onSetActiveTelegrafPlugin('') + onSetSubstepIndex(2, 'streaming') } private handleClickSideBarTab = (telegrafPluginID: string) => { const { - onSetCurrentSubStepIndex, + onSetSubstepIndex, onSetActiveTelegrafPlugin, dataLoaders: {telegrafPlugins}, } = this.props @@ -226,7 +226,7 @@ class OnboardingWizard extends PureComponent { 0 ) - onSetCurrentSubStepIndex(3, index) + onSetSubstepIndex(3, index) onSetActiveTelegrafPlugin(telegrafPluginID) } @@ -247,6 +247,7 @@ class OnboardingWizard extends PureComponent { onSetStepStatus, onSetSetupParams, onSetCurrentStepIndex, + onSetSubstepIndex, onDecrementCurrentStepIndex, onIncrementCurrentStepIndex, } = this.props @@ -256,6 +257,7 @@ class OnboardingWizard extends PureComponent { stepTitles: this.stepTitles, currentStepIndex, onSetCurrentStepIndex, + onSetSubstepIndex, onIncrementCurrentStepIndex, onDecrementCurrentStepIndex, onSetStepStatus, diff --git a/ui/src/onboarding/containers/OnboardingWizardPage.tsx b/ui/src/onboarding/containers/OnboardingWizardPage.tsx index c8d16cdbfa..b89d45e812 100644 --- a/ui/src/onboarding/containers/OnboardingWizardPage.tsx +++ b/ui/src/onboarding/containers/OnboardingWizardPage.tsx @@ -61,7 +61,7 @@ export class OnboardingWizardPage extends PureComponent { onDecrementCurrentStepIndex={this.handleDecrementStepIndex} onIncrementCurrentStepIndex={this.handleIncrementStepIndex} onSetCurrentStepIndex={this.setStepIndex} - onSetCurrentSubStepIndex={this.setSubstepIndex} + onSetSubstepIndex={this.setSubstepIndex} currentStepIndex={+params.stepID} onCompleteSetup={this.handleCompleteSetup} /> @@ -74,9 +74,11 @@ export class OnboardingWizardPage extends PureComponent { } private handleDecrementStepIndex = () => { - const {router} = this.props + const { + params: {stepID}, + } = this.props - router.goBack() + this.setStepIndex(+stepID - 1) } private handleIncrementStepIndex = () => {