Merge pull request #1764 from influxdata/feat/onboarding-routing
Handling onboarding with react routerpull/10616/head
commit
3b8578c7d6
|
@ -1,6 +1,7 @@
|
||||||
// Libraries
|
// Libraries
|
||||||
import React, {ReactElement, PureComponent} from 'react'
|
import React, {ReactElement, PureComponent} from 'react'
|
||||||
import {connect} from 'react-redux'
|
import {connect} from 'react-redux'
|
||||||
|
import {InjectedRouter} from 'react-router'
|
||||||
|
|
||||||
// APIs
|
// APIs
|
||||||
import {getSetupStatus} from 'src/onboarding/apis'
|
import {getSetupStatus} from 'src/onboarding/apis'
|
||||||
|
@ -10,8 +11,9 @@ import {notify as notifyAction} from 'src/shared/actions/notifications'
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||||
import OnboardingWizard from 'src/onboarding/containers/OnboardingWizard'
|
|
||||||
import Notifications from 'src/shared/components/notifications/Notifications'
|
// Utils
|
||||||
|
import {isOnboardingURL} from 'src/onboarding/utils'
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import {Notification, NotificationFunc, RemoteDataState} from 'src/types'
|
import {Notification, NotificationFunc, RemoteDataState} from 'src/types'
|
||||||
|
@ -24,6 +26,7 @@ interface State {
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
links: Links
|
links: Links
|
||||||
|
router: InjectedRouter
|
||||||
children: ReactElement<any>
|
children: ReactElement<any>
|
||||||
notify: (message: Notification | NotificationFunc) => void
|
notify: (message: Notification | NotificationFunc) => void
|
||||||
}
|
}
|
||||||
|
@ -40,35 +43,35 @@ export class Setup extends PureComponent<Props, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public async componentDidMount() {
|
public async componentDidMount() {
|
||||||
const {links} = this.props
|
const {links, router} = this.props
|
||||||
|
|
||||||
|
if (isOnboardingURL()) {
|
||||||
|
this.setState({
|
||||||
|
loading: RemoteDataState.Done,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const isSetupAllowed = await getSetupStatus(links.setup)
|
const isSetupAllowed = await getSetupStatus(links.setup)
|
||||||
this.setState({
|
this.setState({
|
||||||
loading: RemoteDataState.Done,
|
loading: RemoteDataState.Done,
|
||||||
isSetupComplete: !isSetupAllowed,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (!isSetupAllowed) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
router.push('/onboarding/0')
|
||||||
}
|
}
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
const {isSetupComplete} = this.state
|
|
||||||
if (this.isLoading) {
|
if (this.isLoading) {
|
||||||
return <div className="page-spinner" />
|
return <div className="page-spinner" />
|
||||||
}
|
|
||||||
if (!isSetupComplete) {
|
|
||||||
return (
|
|
||||||
<div className="chronograf-root">
|
|
||||||
<Notifications inPresentationMode={true} />
|
|
||||||
<OnboardingWizard onCompleteSetup={this.handleCompleteSetup} />
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
return this.props.children && React.cloneElement(this.props.children)
|
return this.props.children && React.cloneElement(this.props.children)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public handleCompleteSetup = () => {
|
|
||||||
this.setState({isSetupComplete: true})
|
|
||||||
}
|
|
||||||
|
|
||||||
private get isLoading(): boolean {
|
private get isLoading(): boolean {
|
||||||
const {loading} = this.state
|
const {loading} = this.state
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -33,6 +33,8 @@ import GetLinks from 'src/shared/containers/GetLinks'
|
||||||
import GetMe from 'src/shared/containers/GetMe'
|
import GetMe from 'src/shared/containers/GetMe'
|
||||||
import SourcesPage from 'src/sources/components/SourcesPage'
|
import SourcesPage from 'src/sources/components/SourcesPage'
|
||||||
|
|
||||||
|
import OnboardingWizardPage from 'src/onboarding/containers/OnboardingWizardPage'
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
import {disablePresentationMode} from 'src/shared/actions/app'
|
import {disablePresentationMode} from 'src/shared/actions/app'
|
||||||
|
|
||||||
|
@ -77,6 +79,14 @@ class Root extends PureComponent {
|
||||||
<Router history={history}>
|
<Router history={history}>
|
||||||
<Route component={GetLinks}>
|
<Route component={GetLinks}>
|
||||||
<Route component={Setup}>
|
<Route component={Setup}>
|
||||||
|
<Route
|
||||||
|
path="/onboarding/:stepID"
|
||||||
|
component={OnboardingWizardPage}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/onboarding/:stepID/:substepID"
|
||||||
|
component={OnboardingWizardPage}
|
||||||
|
/>
|
||||||
<Route component={Signin}>
|
<Route component={Signin}>
|
||||||
<Route component={GetMe}>
|
<Route component={GetMe}>
|
||||||
<Route component={GetOrganizations}>
|
<Route component={GetOrganizations}>
|
||||||
|
@ -116,8 +126,8 @@ class Root extends PureComponent {
|
||||||
</Route>
|
</Route>
|
||||||
</Route>
|
</Route>
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="*" component={NotFound} />
|
|
||||||
</Route>
|
</Route>
|
||||||
|
<Route path="*" component={NotFound} />
|
||||||
</Router>
|
</Router>
|
||||||
</Provider>
|
</Provider>
|
||||||
)
|
)
|
||||||
|
|
|
@ -4,12 +4,7 @@ import {StepStatus} from 'src/clockface/constants/wizard'
|
||||||
// Types
|
// Types
|
||||||
import {SetupParams} from 'src/onboarding/apis'
|
import {SetupParams} from 'src/onboarding/apis'
|
||||||
|
|
||||||
export type Action =
|
export type Action = SetSetupParams | SetStepStatus
|
||||||
| SetSetupParams
|
|
||||||
| IncrementCurrentStepIndex
|
|
||||||
| DecrementCurrentStepIndex
|
|
||||||
| SetCurrentStepIndex
|
|
||||||
| SetStepStatus
|
|
||||||
|
|
||||||
interface SetSetupParams {
|
interface SetSetupParams {
|
||||||
type: 'SET_SETUP_PARAMS'
|
type: 'SET_SETUP_PARAMS'
|
||||||
|
@ -21,32 +16,6 @@ export const setSetupParams = (setupParams: SetupParams): SetSetupParams => ({
|
||||||
payload: {setupParams},
|
payload: {setupParams},
|
||||||
})
|
})
|
||||||
|
|
||||||
interface SetCurrentStepIndex {
|
|
||||||
type: 'SET_CURRENT_STEP_INDEX'
|
|
||||||
payload: {index: number}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const setCurrentStepIndex = (index: number): SetCurrentStepIndex => ({
|
|
||||||
type: 'SET_CURRENT_STEP_INDEX',
|
|
||||||
payload: {index},
|
|
||||||
})
|
|
||||||
|
|
||||||
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 SetStepStatus {
|
interface SetStepStatus {
|
||||||
type: 'SET_STEP_STATUS'
|
type: 'SET_STEP_STATUS'
|
||||||
payload: {index: number; status: StepStatus}
|
payload: {index: number; status: StepStatus}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
// Libraries
|
// Libraries
|
||||||
import React, {PureComponent} from 'react'
|
import React, {PureComponent} from 'react'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
|
import {withRouter, WithRouterProps} from 'react-router'
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||||
|
@ -16,27 +17,44 @@ import ConfigureDataSourceSwitcher from 'src/onboarding/components/configureStep
|
||||||
import {OnboardingStepProps} from 'src/onboarding/containers/OnboardingWizard'
|
import {OnboardingStepProps} from 'src/onboarding/containers/OnboardingWizard'
|
||||||
import {TelegrafPlugin, DataLoaderType} from 'src/types/v2/dataLoaders'
|
import {TelegrafPlugin, DataLoaderType} from 'src/types/v2/dataLoaders'
|
||||||
|
|
||||||
export interface Props extends OnboardingStepProps {
|
export interface OwnProps extends OnboardingStepProps {
|
||||||
telegrafPlugins: TelegrafPlugin[]
|
telegrafPlugins: TelegrafPlugin[]
|
||||||
type: DataLoaderType
|
type: DataLoaderType
|
||||||
}
|
}
|
||||||
|
|
||||||
interface State {
|
interface RouterProps {
|
||||||
currentDataSourceIndex: number
|
params: {
|
||||||
|
stepID: string
|
||||||
|
substepID: string
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Props = OwnProps & WithRouterProps & RouterProps
|
||||||
|
|
||||||
@ErrorHandling
|
@ErrorHandling
|
||||||
class ConfigureDataSourceStep extends PureComponent<Props, State> {
|
class ConfigureDataSourceStep extends PureComponent<Props> {
|
||||||
constructor(props: Props) {
|
constructor(props: Props) {
|
||||||
super(props)
|
super(props)
|
||||||
|
}
|
||||||
|
|
||||||
this.state = {
|
public componentDidMount() {
|
||||||
currentDataSourceIndex: 0,
|
const {
|
||||||
|
router,
|
||||||
|
params: {stepID, substepID},
|
||||||
|
} = this.props
|
||||||
|
|
||||||
|
if (substepID === undefined) {
|
||||||
|
router.replace(`/onboarding/${stepID}/0`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
const {telegrafPlugins, type, setupParams} = this.props
|
const {
|
||||||
|
telegrafPlugins,
|
||||||
|
type,
|
||||||
|
params: {substepID},
|
||||||
|
setupParams,
|
||||||
|
} = this.props
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="onboarding-step">
|
<div className="onboarding-step">
|
||||||
|
@ -44,8 +62,8 @@ class ConfigureDataSourceStep extends PureComponent<Props, State> {
|
||||||
bucket={_.get(setupParams, 'bucket', '')}
|
bucket={_.get(setupParams, 'bucket', '')}
|
||||||
org={_.get(setupParams, 'org', '')}
|
org={_.get(setupParams, 'org', '')}
|
||||||
telegrafPlugins={telegrafPlugins}
|
telegrafPlugins={telegrafPlugins}
|
||||||
currentIndex={this.state.currentDataSourceIndex}
|
|
||||||
dataLoaderType={type}
|
dataLoaderType={type}
|
||||||
|
currentIndex={+substepID}
|
||||||
/>
|
/>
|
||||||
<div className="wizard-button-bar">
|
<div className="wizard-button-bar">
|
||||||
<Button
|
<Button
|
||||||
|
@ -68,26 +86,27 @@ class ConfigureDataSourceStep extends PureComponent<Props, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleNext = () => {
|
private handleNext = () => {
|
||||||
const {onIncrementCurrentStepIndex, telegrafPlugins} = this.props
|
const {
|
||||||
const {currentDataSourceIndex} = this.state
|
onIncrementCurrentStepIndex,
|
||||||
|
telegrafPlugins,
|
||||||
|
params: {substepID, stepID},
|
||||||
|
router,
|
||||||
|
} = this.props
|
||||||
|
|
||||||
if (currentDataSourceIndex >= telegrafPlugins.length - 1) {
|
const index = +substepID
|
||||||
|
|
||||||
|
if (index >= telegrafPlugins.length - 1) {
|
||||||
onIncrementCurrentStepIndex()
|
onIncrementCurrentStepIndex()
|
||||||
} else {
|
} else {
|
||||||
this.setState({currentDataSourceIndex: currentDataSourceIndex + 1})
|
router.push(`/onboarding/${stepID}/${index + 1}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private handlePrevious = () => {
|
private handlePrevious = () => {
|
||||||
const {onDecrementCurrentStepIndex} = this.props
|
const {router} = this.props
|
||||||
const {currentDataSourceIndex} = this.state
|
|
||||||
|
|
||||||
if (currentDataSourceIndex === 0) {
|
router.goBack()
|
||||||
onDecrementCurrentStepIndex()
|
|
||||||
} else {
|
|
||||||
this.setState({currentDataSourceIndex: currentDataSourceIndex - 1})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ConfigureDataSourceStep
|
export default withRouter<OwnProps>(ConfigureDataSourceStep)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
// Libraries
|
// Libraries
|
||||||
import React, {PureComponent} from 'react'
|
import React, {PureComponent} from 'react'
|
||||||
|
import {withRouter, WithRouterProps} from 'react-router'
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||||
|
@ -21,7 +22,7 @@ import {
|
||||||
TelegrafPluginName,
|
TelegrafPluginName,
|
||||||
} from 'src/types/v2/dataLoaders'
|
} from 'src/types/v2/dataLoaders'
|
||||||
|
|
||||||
export interface Props extends OnboardingStepProps {
|
export interface OwnProps extends OnboardingStepProps {
|
||||||
bucket: string
|
bucket: string
|
||||||
telegrafPlugins: TelegrafPlugin[]
|
telegrafPlugins: TelegrafPlugin[]
|
||||||
type: DataLoaderType
|
type: DataLoaderType
|
||||||
|
@ -30,6 +31,15 @@ export interface Props extends OnboardingStepProps {
|
||||||
onSetDataLoadersType: (type: DataLoaderType) => void
|
onSetDataLoadersType: (type: DataLoaderType) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface RouterProps {
|
||||||
|
params: {
|
||||||
|
stepID: string
|
||||||
|
substepID: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Props = OwnProps & RouterProps & WithRouterProps
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
showStreamingSources: boolean
|
showStreamingSources: boolean
|
||||||
}
|
}
|
||||||
|
@ -72,7 +82,7 @@ class SelectDataSourceStep extends PureComponent<Props, State> {
|
||||||
|
|
||||||
private get title(): string {
|
private get title(): string {
|
||||||
const {bucket} = this.props
|
const {bucket} = this.props
|
||||||
if (this.state.showStreamingSources) {
|
if (this.isStreaming) {
|
||||||
return `Select Streaming Data Sources to add to ${bucket ||
|
return `Select Streaming Data Sources to add to ${bucket ||
|
||||||
'your bucket'}`
|
'your bucket'}`
|
||||||
}
|
}
|
||||||
|
@ -80,10 +90,7 @@ class SelectDataSourceStep extends PureComponent<Props, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private get selector(): JSX.Element {
|
private get selector(): JSX.Element {
|
||||||
if (
|
if (this.props.type === DataLoaderType.Streaming && this.isStreaming) {
|
||||||
this.props.type === DataLoaderType.Streaming &&
|
|
||||||
this.state.showStreamingSources
|
|
||||||
) {
|
|
||||||
return (
|
return (
|
||||||
<StreamingDataSourceSelector
|
<StreamingDataSourceSelector
|
||||||
telegrafPlugins={this.props.telegrafPlugins}
|
telegrafPlugins={this.props.telegrafPlugins}
|
||||||
|
@ -100,11 +107,13 @@ class SelectDataSourceStep extends PureComponent<Props, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleClickNext = () => {
|
private handleClickNext = () => {
|
||||||
if (
|
const {
|
||||||
this.props.type === DataLoaderType.Streaming &&
|
router,
|
||||||
!this.state.showStreamingSources
|
params: {stepID},
|
||||||
) {
|
} = this.props
|
||||||
this.setState({showStreamingSources: true})
|
|
||||||
|
if (this.props.type === DataLoaderType.Streaming && !this.isStreaming) {
|
||||||
|
router.push(`/onboarding/${stepID}/streaming`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,11 +121,6 @@ class SelectDataSourceStep extends PureComponent<Props, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleClickBack = () => {
|
private handleClickBack = () => {
|
||||||
if (this.props.type === DataLoaderType.Streaming) {
|
|
||||||
this.setState({showStreamingSources: false})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
this.props.onDecrementCurrentStepIndex()
|
this.props.onDecrementCurrentStepIndex()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,6 +149,10 @@ class SelectDataSourceStep extends PureComponent<Props, State> {
|
||||||
}
|
}
|
||||||
this.props.onAddTelegrafPlugin(plugin)
|
this.props.onAddTelegrafPlugin(plugin)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private get isStreaming(): boolean {
|
||||||
|
return this.props.params.substepID === 'streaming'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default SelectDataSourceStep
|
export default withRouter<OwnProps>(SelectDataSourceStep)
|
||||||
|
|
|
@ -16,13 +16,8 @@ import OnboardingStepSwitcher from 'src/onboarding/components/OnboardingStepSwit
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
import {notify as notifyAction} from 'src/shared/actions/notifications'
|
import {notify as notifyAction} from 'src/shared/actions/notifications'
|
||||||
import {
|
import {setSetupParams, setStepStatus} from 'src/onboarding/actions/steps'
|
||||||
setSetupParams,
|
|
||||||
incrementCurrentStepIndex,
|
|
||||||
decrementCurrentStepIndex,
|
|
||||||
setCurrentStepIndex,
|
|
||||||
setStepStatus,
|
|
||||||
} from 'src/onboarding/actions/steps'
|
|
||||||
import {
|
import {
|
||||||
setDataLoadersType,
|
setDataLoadersType,
|
||||||
addTelegrafPlugin,
|
addTelegrafPlugin,
|
||||||
|
@ -62,14 +57,15 @@ interface OwnProps {
|
||||||
startStep?: number
|
startStep?: number
|
||||||
stepStatuses?: StepStatus[]
|
stepStatuses?: StepStatus[]
|
||||||
onCompleteSetup: () => void
|
onCompleteSetup: () => void
|
||||||
|
currentStepIndex: number
|
||||||
|
onIncrementCurrentStepIndex: () => void
|
||||||
|
onDecrementCurrentStepIndex: () => void
|
||||||
|
onSetCurrentStepIndex: (stepNumber: number) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
interface DispatchProps {
|
interface DispatchProps {
|
||||||
notify: (message: Notification | NotificationFunc) => void
|
notify: (message: Notification | NotificationFunc) => void
|
||||||
onSetSetupParams: typeof setSetupParams
|
onSetSetupParams: typeof setSetupParams
|
||||||
onIncrementCurrentStepIndex: typeof incrementCurrentStepIndex
|
|
||||||
onDecrementCurrentStepIndex: typeof decrementCurrentStepIndex
|
|
||||||
onSetCurrentStepIndex: typeof setCurrentStepIndex
|
|
||||||
onSetStepStatus: typeof setStepStatus
|
onSetStepStatus: typeof setStepStatus
|
||||||
onSetDataLoadersType: typeof setDataLoadersType
|
onSetDataLoadersType: typeof setDataLoadersType
|
||||||
onAddTelegrafPlugin: typeof addTelegrafPlugin
|
onAddTelegrafPlugin: typeof addTelegrafPlugin
|
||||||
|
@ -84,7 +80,6 @@ interface DataLoadersProps {
|
||||||
|
|
||||||
interface StateProps {
|
interface StateProps {
|
||||||
links: Links
|
links: Links
|
||||||
currentStepIndex: number
|
|
||||||
stepStatuses: StepStatus[]
|
stepStatuses: StepStatus[]
|
||||||
setupParams: SetupParams
|
setupParams: SetupParams
|
||||||
dataLoaders: DataLoadersProps
|
dataLoaders: DataLoadersProps
|
||||||
|
@ -238,12 +233,11 @@ class OnboardingWizard extends PureComponent<Props> {
|
||||||
const mstp = ({
|
const mstp = ({
|
||||||
links,
|
links,
|
||||||
onboarding: {
|
onboarding: {
|
||||||
steps: {currentStepIndex, stepStatuses, setupParams},
|
steps: {stepStatuses, setupParams},
|
||||||
dataLoaders,
|
dataLoaders,
|
||||||
},
|
},
|
||||||
}: AppState): StateProps => ({
|
}: AppState): StateProps => ({
|
||||||
links,
|
links,
|
||||||
currentStepIndex,
|
|
||||||
stepStatuses,
|
stepStatuses,
|
||||||
setupParams,
|
setupParams,
|
||||||
dataLoaders,
|
dataLoaders,
|
||||||
|
@ -252,9 +246,6 @@ const mstp = ({
|
||||||
const mdtp: DispatchProps = {
|
const mdtp: DispatchProps = {
|
||||||
notify: notifyAction,
|
notify: notifyAction,
|
||||||
onSetSetupParams: setSetupParams,
|
onSetSetupParams: setSetupParams,
|
||||||
onDecrementCurrentStepIndex: decrementCurrentStepIndex,
|
|
||||||
onIncrementCurrentStepIndex: incrementCurrentStepIndex,
|
|
||||||
onSetCurrentStepIndex: setCurrentStepIndex,
|
|
||||||
onSetStepStatus: setStepStatus,
|
onSetStepStatus: setStepStatus,
|
||||||
onSetDataLoadersType: setDataLoadersType,
|
onSetDataLoadersType: setDataLoadersType,
|
||||||
onAddTelegrafPlugin: addTelegrafPlugin,
|
onAddTelegrafPlugin: addTelegrafPlugin,
|
||||||
|
|
|
@ -0,0 +1,109 @@
|
||||||
|
// Libraries
|
||||||
|
import React, {ReactElement, PureComponent} from 'react'
|
||||||
|
import {connect} from 'react-redux'
|
||||||
|
import {withRouter, WithRouterProps} from 'react-router'
|
||||||
|
|
||||||
|
// Actions
|
||||||
|
import {notify as notifyAction} from 'src/shared/actions/notifications'
|
||||||
|
|
||||||
|
// Components
|
||||||
|
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||||
|
import OnboardingWizard from 'src/onboarding/containers/OnboardingWizard'
|
||||||
|
import Notifications from 'src/shared/components/notifications/Notifications'
|
||||||
|
|
||||||
|
// Types
|
||||||
|
import {Notification, NotificationFunc, RemoteDataState} from 'src/types'
|
||||||
|
import {Links} from 'src/types/v2/links'
|
||||||
|
|
||||||
|
interface State {
|
||||||
|
loading: RemoteDataState
|
||||||
|
isSetupComplete: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PassedProps {
|
||||||
|
children: ReactElement<any>
|
||||||
|
params: {
|
||||||
|
stepID: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ConnectedStateProps {
|
||||||
|
links: Links
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ConnectedDispatchProps {
|
||||||
|
notify: (message: Notification | NotificationFunc) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
type Props = PassedProps &
|
||||||
|
WithRouterProps &
|
||||||
|
ConnectedStateProps &
|
||||||
|
ConnectedDispatchProps
|
||||||
|
|
||||||
|
@ErrorHandling
|
||||||
|
export class OnboardingWizardPage extends PureComponent<Props, State> {
|
||||||
|
constructor(props: Props) {
|
||||||
|
super(props)
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
loading: RemoteDataState.NotStarted,
|
||||||
|
isSetupComplete: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public render() {
|
||||||
|
const {params} = this.props
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="chronograf-root">
|
||||||
|
<Notifications inPresentationMode={true} />
|
||||||
|
<OnboardingWizard
|
||||||
|
onDecrementCurrentStepIndex={this.handleDecrementStepIndex}
|
||||||
|
onIncrementCurrentStepIndex={this.handleIncrementStepIndex}
|
||||||
|
onSetCurrentStepIndex={this.setStepIndex}
|
||||||
|
currentStepIndex={+params.stepID}
|
||||||
|
onCompleteSetup={this.handleCompleteSetup}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
public handleCompleteSetup = () => {
|
||||||
|
this.setState({isSetupComplete: true})
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleDecrementStepIndex = () => {
|
||||||
|
const {router} = this.props
|
||||||
|
|
||||||
|
router.goBack()
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleIncrementStepIndex = () => {
|
||||||
|
const {
|
||||||
|
params: {stepID},
|
||||||
|
} = this.props
|
||||||
|
|
||||||
|
this.setStepIndex(+stepID + 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
private setStepIndex = (index: number) => {
|
||||||
|
const {router} = this.props
|
||||||
|
|
||||||
|
router.push(`/onboarding/${index}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const mstp = ({links}) => ({links})
|
||||||
|
|
||||||
|
const mdtp = {
|
||||||
|
notify: notifyAction,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default connect<
|
||||||
|
ConnectedStateProps,
|
||||||
|
ConnectedDispatchProps,
|
||||||
|
PassedProps
|
||||||
|
>(
|
||||||
|
mstp,
|
||||||
|
mdtp
|
||||||
|
)(withRouter<Props>(OnboardingWizardPage))
|
|
@ -6,13 +6,11 @@ import {Action} from 'src/onboarding/actions/steps'
|
||||||
import {SetupParams} from 'src/onboarding/apis'
|
import {SetupParams} from 'src/onboarding/apis'
|
||||||
|
|
||||||
export interface OnboardingStepsState {
|
export interface OnboardingStepsState {
|
||||||
currentStepIndex: number
|
|
||||||
stepStatuses: StepStatus[]
|
stepStatuses: StepStatus[]
|
||||||
setupParams: SetupParams
|
setupParams: SetupParams
|
||||||
}
|
}
|
||||||
|
|
||||||
const INITIAL_STATE: OnboardingStepsState = {
|
const INITIAL_STATE: OnboardingStepsState = {
|
||||||
currentStepIndex: 0,
|
|
||||||
stepStatuses: new Array(6).fill(StepStatus.Incomplete),
|
stepStatuses: new Array(6).fill(StepStatus.Incomplete),
|
||||||
setupParams: null,
|
setupParams: null,
|
||||||
}
|
}
|
||||||
|
@ -24,12 +22,6 @@ export default (
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case 'SET_SETUP_PARAMS':
|
case 'SET_SETUP_PARAMS':
|
||||||
return {...state, setupParams: action.payload.setupParams}
|
return {...state, setupParams: action.payload.setupParams}
|
||||||
case 'INCREMENT_CURRENT_STEP_INDEX':
|
|
||||||
return {...state, currentStepIndex: state.currentStepIndex + 1}
|
|
||||||
case 'DECREMENT_CURRENT_STEP_INDEX':
|
|
||||||
return {...state, currentStepIndex: state.currentStepIndex - 1}
|
|
||||||
case 'SET_CURRENT_STEP_INDEX':
|
|
||||||
return {...state, currentStepIndex: action.payload.index}
|
|
||||||
case 'SET_STEP_STATUS':
|
case 'SET_STEP_STATUS':
|
||||||
const stepStatuses = [...state.stepStatuses]
|
const stepStatuses = [...state.stepStatuses]
|
||||||
stepStatuses[action.payload.index] = action.payload.status
|
stepStatuses[action.payload.index] = action.payload.status
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
export const isOnboardingURL = () => {
|
||||||
|
return !!window.location.pathname.match(/\/onboarding/)
|
||||||
|
}
|
Loading…
Reference in New Issue