Skip to content

Commit

Permalink
[Logs onboarding] Add client side routing support for individual steps (
Browse files Browse the repository at this point in the history
#161230)

Closes #159500.

This PR focuses on adding client-site routing support to the wizard
developed for observability_onboarding plugin.

### Changes
- Added routes for each step of the wizard.
- Added support for `history.push` and `history.goBack` in wizard
context.
- Added basePath to wizard provider.



https://github.com/elastic/kibana/assets/1313018/c32e25b3-2470-41a4-8c34-f2dd5ea7c366
  • Loading branch information
yngrdyn authored Jul 14, 2023
1 parent 395d4c0 commit 86e7aca
Show file tree
Hide file tree
Showing 14 changed files with 283 additions and 149 deletions.
29 changes: 27 additions & 2 deletions x-pack/plugins/observability_onboarding/public/application/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,14 @@ import { euiDarkVars, euiLightVars } from '@kbn/ui-theme';
import React from 'react';
import ReactDOM from 'react-dom';
import { RouteComponentProps, RouteProps } from 'react-router-dom';
import { customLogsRoutes } from '../components/app/custom_logs/wizard';
import { ObservabilityOnboardingHeaderActionMenu } from '../components/app/header_action_menu';
import {
ObservabilityOnboardingPluginSetupDeps,
ObservabilityOnboardingPluginStartDeps,
} from '../plugin';
import { routes } from '../routes';
import { baseRoutes, routes } from '../routes';
import { CustomLogs } from '../routes/templates/custom_logs';

export type BreadcrumbTitle<
T extends { [K in keyof T]?: string | undefined } = {}
Expand All @@ -55,19 +57,42 @@ export const breadcrumbsApp = {
};

function App() {
const customLogRoutesPaths = Object.keys(customLogsRoutes);

return (
<>
<Routes>
{Object.keys(routes).map((key) => {
{Object.keys(baseRoutes).map((key) => {
const path = key as keyof typeof routes;
const { handler, exact } = routes[path];
const Wrapper = () => {
return handler();
};

return (
<Route key={path} path={path} exact={exact} component={Wrapper} />
);
})}
<Route exact path={customLogRoutesPaths}>
<CustomLogs>
{customLogRoutesPaths.map((key) => {
const path = key as keyof typeof routes;
const { handler, exact } = routes[path];
const Wrapper = () => {
return handler();
};

return (
<Route
key={path}
path={path}
exact={exact}
component={Wrapper}
/>
);
})}
</CustomLogs>
</Route>
</Routes>
</>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { EuiButton } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
import { useHistory } from 'react-router-dom';
import { useWizard } from '.';

export function BackButton({ onBack }: { onBack: () => void }) {
const { getPath } = useWizard();
const history = useHistory();

return (
<EuiButton
color="text"
onClick={onBack}
disabled={history.length === 1 || getPath().length === 1}
>
{i18n.translate('xpack.observability_onboarding.steps.back', {
defaultMessage: 'Back',
})}
</EuiButton>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import {
StepPanelContent,
StepPanelFooter,
} from '../../../shared/step_panel';
import { BackButton } from './back_button';
import { getFilename, replaceSpecialChars } from './get_filename';

export function ConfigureLogs() {
Expand All @@ -51,10 +52,6 @@ export function ConfigureLogs() {

const logFilePathNotConfigured = logFilePaths.every((filepath) => !filepath);

function onBack() {
goBack();
}

function onContinue() {
setState((state) => ({
...state,
Expand Down Expand Up @@ -100,11 +97,7 @@ export function ConfigureLogs() {
panelFooter={
<StepPanelFooter
items={[
<EuiButton color="text" onClick={onBack}>
{i18n.translate('xpack.observability_onboarding.steps.back', {
defaultMessage: 'Back',
})}
</EuiButton>,
<BackButton onBack={goBack} />,
<EuiButton
color="primary"
fill
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@
* 2.0.
*/

import { ConfigureLogs } from './configure_logs';
import { SelectLogs } from './select_logs';
import { InstallElasticAgent } from './install_elastic_agent';
import { ComponentType } from 'react';
import { createWizardContext } from '../../../../context/create_wizard_context';
import { ConfigureLogs } from './configure_logs';
import { Inspect } from './inspect';
import { InstallElasticAgent } from './install_elastic_agent';
import { SelectLogs } from './select_logs';

interface WizardState {
datasetName: string;
Expand Down Expand Up @@ -44,15 +45,28 @@ const initialState: WizardState = {
onboardingId: '',
};

const { Provider, Step, useWizard } = createWizardContext({
export type CustomLogsSteps =
| 'selectLogs'
| 'configureLogs'
| 'installElasticAgent'
| 'inspect';

const steps: Record<CustomLogsSteps, ComponentType<{}>> = {
selectLogs: SelectLogs,
configureLogs: ConfigureLogs,
installElasticAgent: InstallElasticAgent,
inspect: Inspect,
};

const {
Provider,
useWizard,
routes: customLogsRoutes,
} = createWizardContext({
initialState,
initialStep: 'selectLogs',
steps: {
selectLogs: SelectLogs,
configureLogs: ConfigureLogs,
installElasticAgent: InstallElasticAgent,
inspect: Inspect,
},
steps,
basePath: '/customLogs',
});

export { Provider, Step, useWizard };
export { Provider, useWizard, customLogsRoutes };
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,21 @@
*/

import React from 'react';
import { EuiButton, EuiTitle, EuiSpacer } from '@elastic/eui';
import { EuiTitle, EuiSpacer } from '@elastic/eui';
import {
StepPanel,
StepPanelContent,
StepPanelFooter,
} from '../../../shared/step_panel';
import { useWizard } from '.';
import { BackButton } from './back_button';

export function Inspect() {
const { goBack, getState, getPath, getUsage } = useWizard();
return (
<StepPanel
title="Inspect wizard"
panelFooter={
<StepPanelFooter
items={[
<EuiButton color="text" onClick={goBack}>
Back
</EuiButton>,
]}
/>
}
panelFooter={<StepPanelFooter items={[<BackButton onBack={goBack} />]} />}
>
<StepPanelContent>
<EuiTitle size="s">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,12 @@ import {
StepPanelFooter,
} from '../../../shared/step_panel';
import { ApiKeyBanner } from './api_key_banner';
import { BackButton } from './back_button';

type ElasticAgentPlatform = 'linux-tar' | 'macos' | 'windows';
export function InstallElasticAgent() {
const { navigateToKibanaUrl } = useKibanaNavigation();
const { goBack, goToStep, getState, setState, CurrentStep } = useWizard();
const { goBack, goToStep, getState, setState } = useWizard();
const wizardState = getState();
const [elasticAgentPlatform, setElasticAgentPlatform] =
useState<ElasticAgentPlatform>('linux-tar');
Expand All @@ -51,10 +52,6 @@ export function InstallElasticAgent() {
navigateToKibanaUrl('/app/logs/stream');
}

function onBack() {
goBack();
}

function onAutoDownloadConfig() {
setState((state) => ({
...state,
Expand All @@ -64,10 +61,7 @@ export function InstallElasticAgent() {

const { data: monitoringRole, status: monitoringRoleStatus } = useFetcher(
(callApi) => {
if (
CurrentStep === InstallElasticAgent &&
!hasAlreadySavedFlow(getState())
) {
if (!hasAlreadySavedFlow(getState())) {
return callApi(
'GET /internal/observability_onboarding/custom_logs/privileges'
);
Expand All @@ -77,11 +71,9 @@ export function InstallElasticAgent() {
);

const { data: setup } = useFetcher((callApi) => {
if (CurrentStep === InstallElasticAgent) {
return callApi(
'GET /internal/observability_onboarding/custom_logs/install_shipper_setup'
);
}
return callApi(
'GET /internal/observability_onboarding/custom_logs/install_shipper_setup'
);
}, []);

const {
Expand All @@ -97,11 +89,7 @@ export function InstallElasticAgent() {
customConfigurations,
logFilePaths,
} = getState();
if (
CurrentStep === InstallElasticAgent &&
!hasAlreadySavedFlow(getState()) &&
monitoringRole?.hasPrivileges
) {
if (!hasAlreadySavedFlow(getState()) && monitoringRole?.hasPrivileges) {
return callApi(
'POST /internal/observability_onboarding/custom_logs/save',
{
Expand Down Expand Up @@ -133,7 +121,7 @@ export function InstallElasticAgent() {
customConfigurations,
logFilePaths,
} = getState();
if (CurrentStep === InstallElasticAgent && onboardingId) {
if (onboardingId) {
return callApi(
'PUT /internal/observability_onboarding/custom_logs/{onboardingId}/save',
{
Expand All @@ -158,11 +146,7 @@ export function InstallElasticAgent() {

const { data: yamlConfig = '', status: yamlConfigStatus } = useFetcher(
(callApi) => {
if (
CurrentStep === InstallElasticAgent &&
apiKeyEncoded &&
onboardingId
) {
if (apiKeyEncoded && onboardingId) {
return callApi(
'GET /internal/observability_onboarding/elastic_agent/config',
{
Expand Down Expand Up @@ -190,7 +174,7 @@ export function InstallElasticAgent() {
refetch: refetchProgress,
} = useFetcher(
(callApi) => {
if (CurrentStep === InstallElasticAgent && onboardingId) {
if (onboardingId) {
return callApi(
'GET /internal/observability_onboarding/custom_logs/{onboardingId}/progress',
{ params: { path: { onboardingId } } }
Expand All @@ -208,8 +192,7 @@ export function InstallElasticAgent() {
refetchProgress();
}, 2000);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [progressSucceded]);
}, [progressSucceded, refetchProgress]);

const getStep = useCallback(
({ id, incompleteTitle, loadingTitle, completedTitle }) => {
Expand Down Expand Up @@ -270,11 +253,7 @@ export function InstallElasticAgent() {
panelFooter={
<StepPanelFooter
items={[
<EuiButton color="text" onClick={onBack}>
{i18n.translate('xpack.observability_onboarding.steps.back', {
defaultMessage: 'Back',
})}
</EuiButton>,
<BackButton onBack={goBack} />,
<EuiFlexGroup justifyContent="flexEnd" alignItems="center">
<EuiFlexItem grow={false}>
<EuiButtonEmpty onClick={onInspect}>
Expand Down
Loading

0 comments on commit 86e7aca

Please sign in to comment.