mirror of
https://github.com/elastic/kibana.git
synced 2025-06-27 18:51:07 -04:00
[Onboarding] Create guided_onboarding plugin (#138611)
* [Guided onboarding] Smashed commit of all POC work for guided onboarding and guided onboarding example plugins * [Guided onboarding] Fixed type errors * [Guided onboarding] Removed guidedOnboardingExample limit * [Guided onboarding] Fixed a functonal test for exposed configs * [Guided onboarding] Fixed plugin limit * [Guided onboarding] Added more information to the example plugin * [Guided onboarding] Fixed no-console error * [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix' * [Guided onboarding] Fixed snake case errors * move guided_onboarding out of x-pack Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Alison Goryachev <alison.goryachev@elastic.co>
This commit is contained in:
parent
7d6b5c6eb2
commit
95086f4365
41 changed files with 1666 additions and 0 deletions
7
examples/guided_onboarding_example/.i18nrc.json
Executable file
7
examples/guided_onboarding_example/.i18nrc.json
Executable file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"prefix": "guidedOnboardingExample",
|
||||
"paths": {
|
||||
"guidedOnboardingExample": "."
|
||||
},
|
||||
"translations": ["translations/ja-JP.json"]
|
||||
}
|
9
examples/guided_onboarding_example/README.md
Executable file
9
examples/guided_onboarding_example/README.md
Executable file
|
@ -0,0 +1,9 @@
|
|||
# guidedOnboardingExample
|
||||
|
||||
A Kibana plugin
|
||||
|
||||
---
|
||||
|
||||
## Development
|
||||
|
||||
See the [kibana contributing guide](https://github.com/elastic/kibana/blob/main/CONTRIBUTING.md) for instructions setting up your development environment.
|
10
examples/guided_onboarding_example/common/index.ts
Executable file
10
examples/guided_onboarding_example/common/index.ts
Executable file
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export const PLUGIN_ID = 'guidedOnboardingExample';
|
||||
export const PLUGIN_NAME = 'guidedOnboardingExample';
|
14
examples/guided_onboarding_example/kibana.json
Executable file
14
examples/guided_onboarding_example/kibana.json
Executable file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"id": "guidedOnboardingExample",
|
||||
"version": "1.0.0",
|
||||
"kibanaVersion": "kibana",
|
||||
"owner": {
|
||||
"name": "platform-onboarding",
|
||||
"githubTeam": "platform-onboarding"
|
||||
},
|
||||
"description": "Example plugin to consume guidedOnboarding",
|
||||
"server": false,
|
||||
"ui": true,
|
||||
"requiredPlugins": ["navigation", "guidedOnboarding"],
|
||||
"optionalPlugins": []
|
||||
}
|
30
examples/guided_onboarding_example/public/application.tsx
Executable file
30
examples/guided_onboarding_example/public/application.tsx
Executable file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { AppMountParameters, CoreStart } from '@kbn/core/public';
|
||||
import { AppPluginStartDependencies } from './types';
|
||||
import { GuidedOnboardingExampleApp } from './components/app';
|
||||
|
||||
export const renderApp = (
|
||||
{ notifications }: CoreStart,
|
||||
{ guidedOnboarding }: AppPluginStartDependencies,
|
||||
{ element, history }: AppMountParameters
|
||||
) => {
|
||||
ReactDOM.render(
|
||||
<GuidedOnboardingExampleApp
|
||||
notifications={notifications}
|
||||
guidedOnboarding={guidedOnboarding}
|
||||
history={history}
|
||||
/>,
|
||||
element
|
||||
);
|
||||
|
||||
return () => ReactDOM.unmountComponentAtNode(element);
|
||||
};
|
70
examples/guided_onboarding_example/public/components/app.tsx
Executable file
70
examples/guided_onboarding_example/public/components/app.tsx
Executable file
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { FormattedMessage, I18nProvider } from '@kbn/i18n-react';
|
||||
import { Router, Switch, Route } from 'react-router-dom';
|
||||
|
||||
import {
|
||||
EuiPage,
|
||||
EuiPageBody,
|
||||
EuiPageContent_Deprecated as EuiPageContent,
|
||||
EuiPageHeader,
|
||||
EuiTitle,
|
||||
} from '@elastic/eui';
|
||||
|
||||
import { CoreStart, ScopedHistory } from '@kbn/core/public';
|
||||
|
||||
import { GuidedOnboardingPluginStart } from '@kbn/guided-onboarding-plugin/public/types';
|
||||
import { StepTwo } from './step_two';
|
||||
import { StepOne } from './step_one';
|
||||
import { Main } from './main';
|
||||
|
||||
interface GuidedOnboardingExampleAppDeps {
|
||||
notifications: CoreStart['notifications'];
|
||||
guidedOnboarding: GuidedOnboardingPluginStart;
|
||||
history: ScopedHistory;
|
||||
}
|
||||
|
||||
export const GuidedOnboardingExampleApp = (props: GuidedOnboardingExampleAppDeps) => {
|
||||
const { notifications, guidedOnboarding, history } = props;
|
||||
|
||||
return (
|
||||
<I18nProvider>
|
||||
<EuiPage restrictWidth="1000px">
|
||||
<EuiPageBody>
|
||||
<EuiPageHeader>
|
||||
<EuiTitle size="l">
|
||||
<h1>
|
||||
<FormattedMessage
|
||||
id="guidedOnboardingExample.title"
|
||||
defaultMessage="Guided onboarding examples"
|
||||
/>
|
||||
</h1>
|
||||
</EuiTitle>
|
||||
</EuiPageHeader>
|
||||
<EuiPageContent>
|
||||
<Router history={history}>
|
||||
<Switch>
|
||||
<Route exact path="/">
|
||||
<Main notifications={notifications} guidedOnboarding={guidedOnboarding} />
|
||||
</Route>
|
||||
<Route exact path="/stepOne">
|
||||
<StepOne guidedOnboarding={guidedOnboarding} />
|
||||
</Route>
|
||||
<Route exact path="/stepTwo">
|
||||
<StepTwo guidedOnboarding={guidedOnboarding} />
|
||||
</Route>
|
||||
</Switch>
|
||||
</Router>
|
||||
</EuiPageContent>
|
||||
</EuiPageBody>
|
||||
</EuiPage>
|
||||
</I18nProvider>
|
||||
);
|
||||
};
|
255
examples/guided_onboarding_example/public/components/main.tsx
Normal file
255
examples/guided_onboarding_example/public/components/main.tsx
Normal file
|
@ -0,0 +1,255 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import {
|
||||
EuiButton,
|
||||
EuiFieldNumber,
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiFormRow,
|
||||
EuiHorizontalRule,
|
||||
EuiPageContentBody_Deprecated as EuiPageContentBody,
|
||||
EuiPageContentHeader_Deprecated as EuiPageContentHeader,
|
||||
EuiSelect,
|
||||
EuiSpacer,
|
||||
EuiText,
|
||||
EuiTitle,
|
||||
} from '@elastic/eui';
|
||||
import {
|
||||
GuidedOnboardingPluginStart,
|
||||
GuidedOnboardingState,
|
||||
UseCase,
|
||||
} from '@kbn/guided-onboarding-plugin/public';
|
||||
import { CoreStart } from '@kbn/core/public';
|
||||
|
||||
interface MainProps {
|
||||
guidedOnboarding: GuidedOnboardingPluginStart;
|
||||
notifications: CoreStart['notifications'];
|
||||
}
|
||||
export const Main = (props: MainProps) => {
|
||||
const {
|
||||
guidedOnboarding: { guidedOnboardingApi },
|
||||
notifications,
|
||||
} = props;
|
||||
const history = useHistory();
|
||||
const [guideState, setGuideState] = useState<GuidedOnboardingState | undefined>(undefined);
|
||||
|
||||
const [selectedGuide, setSelectedGuide] = useState<
|
||||
GuidedOnboardingState['activeGuide'] | undefined
|
||||
>(undefined);
|
||||
const [selectedStep, setSelectedStep] = useState<GuidedOnboardingState['activeStep'] | undefined>(
|
||||
undefined
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const subscription = guidedOnboardingApi?.fetchGuideState$().subscribe((newState) => {
|
||||
setGuideState(newState);
|
||||
});
|
||||
return () => subscription?.unsubscribe();
|
||||
}, [guidedOnboardingApi]);
|
||||
|
||||
const startGuide = async (guide: UseCase) => {
|
||||
const response = await guidedOnboardingApi?.updateGuideState({
|
||||
activeGuide: guide,
|
||||
activeStep: 'add_data',
|
||||
});
|
||||
|
||||
if (response) {
|
||||
notifications.toasts.addSuccess(
|
||||
i18n.translate('guidedOnboardingExample.startGuide.toastLabel', {
|
||||
defaultMessage: 'Guide (re-)started',
|
||||
})
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const updateGuideState = async () => {
|
||||
const response = await guidedOnboardingApi?.updateGuideState({
|
||||
activeGuide: selectedGuide!,
|
||||
activeStep: selectedStep!,
|
||||
});
|
||||
|
||||
if (response) {
|
||||
notifications.toasts.addSuccess(
|
||||
i18n.translate('guidedOnboardingExample.updateGuideState.toastLabel', {
|
||||
defaultMessage: 'Guide state updated',
|
||||
})
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<EuiPageContentHeader>
|
||||
<EuiTitle>
|
||||
<h2>
|
||||
<FormattedMessage
|
||||
id="guidedOnboardingExample.main.title"
|
||||
defaultMessage="Guided setup state"
|
||||
/>
|
||||
</h2>
|
||||
</EuiTitle>
|
||||
</EuiPageContentHeader>
|
||||
<EuiPageContentBody>
|
||||
<EuiText>
|
||||
<h3>
|
||||
<FormattedMessage
|
||||
id="guidedOnboardingExample.main.currentStateTitle"
|
||||
defaultMessage="Current state"
|
||||
/>
|
||||
</h3>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="guidedOnboardingExample.guidesSelection.state.explanation"
|
||||
defaultMessage="The guide state on this page is updated automatically via an Observable,
|
||||
so there is no need to 'load' the state from the server."
|
||||
/>
|
||||
</p>
|
||||
{guideState ? (
|
||||
<dl>
|
||||
<dt>
|
||||
<FormattedMessage
|
||||
id="guidedOnboardingExample.guidesSelection.state.activeGuideLabel"
|
||||
defaultMessage="Active guide"
|
||||
/>
|
||||
</dt>
|
||||
<dd>{guideState.activeGuide ?? 'undefined'}</dd>
|
||||
|
||||
<dt>
|
||||
<FormattedMessage
|
||||
id="guidedOnboardingExample.guidesSelection.state.activeStepLabel"
|
||||
defaultMessage="Active step"
|
||||
/>
|
||||
</dt>
|
||||
<dd>{guideState.activeStep ?? 'undefined'}</dd>
|
||||
</dl>
|
||||
) : undefined}
|
||||
</EuiText>
|
||||
<EuiHorizontalRule />
|
||||
<EuiText>
|
||||
<h3>
|
||||
<FormattedMessage
|
||||
id="guidedOnboardingExample.main.startGuide.title"
|
||||
defaultMessage="(Re-)Start a guide"
|
||||
/>
|
||||
</h3>
|
||||
</EuiText>
|
||||
<EuiSpacer />
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem>
|
||||
<EuiButton onClick={() => startGuide('search')} fill>
|
||||
<FormattedMessage
|
||||
id="guidedOnboardingExample.guidesSelection.search.buttonLabel"
|
||||
defaultMessage="(Re-)Start search guide"
|
||||
/>
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiButton onClick={() => startGuide('observability')} fill>
|
||||
<FormattedMessage
|
||||
id="guidedOnboardingExample.guidesSelection.observability.buttonLabel"
|
||||
defaultMessage="(Re-)Start observability guide"
|
||||
/>
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiButton onClick={() => startGuide('security')} fill>
|
||||
<FormattedMessage
|
||||
id="guidedOnboardingExample.guidesSelection.security.label"
|
||||
defaultMessage="(Re-)Start security guide"
|
||||
/>
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<EuiSpacer />
|
||||
<EuiHorizontalRule />
|
||||
<EuiText>
|
||||
<h3>
|
||||
<FormattedMessage
|
||||
id="guidedOnboardingExample.main.setGuideState.title"
|
||||
defaultMessage="Set guide state"
|
||||
/>
|
||||
</h3>
|
||||
</EuiText>
|
||||
<EuiSpacer />
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem>
|
||||
<EuiFormRow label="Guide" helpText="Select a guide">
|
||||
<EuiSelect
|
||||
id={'guideSelect'}
|
||||
options={[
|
||||
{ value: 'observability', text: 'observability' },
|
||||
{ value: 'security', text: 'security' },
|
||||
{ value: 'search', text: 'search' },
|
||||
{ value: '', text: 'unset' },
|
||||
]}
|
||||
value={selectedGuide}
|
||||
onChange={(e) => {
|
||||
const value = e.target.value as UseCase;
|
||||
const shouldResetState = value.trim().length === 0;
|
||||
if (shouldResetState) {
|
||||
setSelectedGuide(undefined);
|
||||
setSelectedStep(undefined);
|
||||
} else {
|
||||
setSelectedGuide(value);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</EuiFormRow>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiFormRow label="Step">
|
||||
<EuiFieldNumber
|
||||
value={selectedStep}
|
||||
onChange={(e) => setSelectedStep(e.target.value)}
|
||||
/>
|
||||
</EuiFormRow>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiFormRow hasEmptyLabelSpace>
|
||||
<EuiButton onClick={updateGuideState}>Save</EuiButton>
|
||||
</EuiFormRow>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<EuiSpacer />
|
||||
<EuiHorizontalRule />
|
||||
<EuiText>
|
||||
<h3>
|
||||
<FormattedMessage
|
||||
id="guidedOnboardingExample.main.examplePages.title"
|
||||
defaultMessage="Example pages"
|
||||
/>
|
||||
</h3>
|
||||
</EuiText>
|
||||
<EuiSpacer />
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButton onClick={() => history.push('stepOne')}>
|
||||
<FormattedMessage
|
||||
id="guidedOnboardingExample.main.examplePages.stepOne.link"
|
||||
defaultMessage="Step 1"
|
||||
/>
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButton onClick={() => history.push('stepTwo')}>
|
||||
<FormattedMessage
|
||||
id="guidedOnboardingExample.main.examplePages.stepTwo.link"
|
||||
defaultMessage="Step 2"
|
||||
/>
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiPageContentBody>
|
||||
</>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import {
|
||||
EuiButton,
|
||||
EuiText,
|
||||
EuiTourStep,
|
||||
EuiTitle,
|
||||
EuiPageContentHeader_Deprecated as EuiPageContentHeader,
|
||||
EuiPageContentBody_Deprecated as EuiPageContentBody,
|
||||
EuiSpacer,
|
||||
} from '@elastic/eui';
|
||||
|
||||
import { GuidedOnboardingPluginStart } from '@kbn/guided-onboarding-plugin/public/types';
|
||||
|
||||
interface GuidedOnboardingExampleAppDeps {
|
||||
guidedOnboarding: GuidedOnboardingPluginStart;
|
||||
}
|
||||
|
||||
export const StepOne = ({ guidedOnboarding }: GuidedOnboardingExampleAppDeps) => {
|
||||
const { guidedOnboardingApi } = guidedOnboarding;
|
||||
|
||||
const [isTourStepOpen, setIsTourStepOpen] = useState<boolean>(false);
|
||||
useEffect(() => {
|
||||
const subscription = guidedOnboardingApi?.fetchGuideState$().subscribe((newState) => {
|
||||
const { activeGuide: guide, activeStep: step } = newState;
|
||||
|
||||
if (guide === 'search' && step === 'add_data') {
|
||||
setIsTourStepOpen(true);
|
||||
}
|
||||
});
|
||||
return () => subscription?.unsubscribe();
|
||||
}, [guidedOnboardingApi]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<EuiPageContentHeader>
|
||||
<EuiTitle>
|
||||
<h2>
|
||||
<FormattedMessage
|
||||
id="guidedOnboardingExample.stepOne.title"
|
||||
defaultMessage="Example step Add data"
|
||||
/>
|
||||
</h2>
|
||||
</EuiTitle>
|
||||
</EuiPageContentHeader>
|
||||
<EuiPageContentBody>
|
||||
<EuiText>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="guidedOnboardingExample.guidesSelection.stepOne.explanation"
|
||||
defaultMessage="The code on this page is listening to the guided setup state. If the state is set to
|
||||
Search guide, step Add data, a EUI tour will be displayed, pointing to the button below. Alternatively,
|
||||
the tour can be displayed via a localStorage value or a url param (see step 2)."
|
||||
/>
|
||||
</p>
|
||||
</EuiText>
|
||||
<EuiSpacer />
|
||||
<EuiTourStep
|
||||
content={
|
||||
<EuiText>
|
||||
<p>Click this button to complete step 1.</p>
|
||||
</EuiText>
|
||||
}
|
||||
isStepOpen={isTourStepOpen}
|
||||
minWidth={300}
|
||||
onFinish={() => setIsTourStepOpen(false)}
|
||||
step={1}
|
||||
stepsTotal={1}
|
||||
title="Step Add data"
|
||||
anchorPosition="rightUp"
|
||||
>
|
||||
<EuiButton
|
||||
onClick={async () => {
|
||||
await guidedOnboardingApi?.updateGuideState({
|
||||
activeGuide: 'search',
|
||||
activeStep: 'search_experience',
|
||||
});
|
||||
}}
|
||||
>
|
||||
Complete step 1
|
||||
</EuiButton>
|
||||
</EuiTourStep>
|
||||
</EuiPageContentBody>
|
||||
</>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
import { EuiButton, EuiSpacer, EuiText, EuiTitle, EuiTourStep } from '@elastic/eui';
|
||||
|
||||
import { GuidedOnboardingPluginStart } from '@kbn/guided-onboarding-plugin/public/types';
|
||||
import { useHistory, useLocation } from 'react-router-dom';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import {
|
||||
EuiPageContentHeader_Deprecated as EuiPageContentHeader,
|
||||
EuiPageContentBody_Deprecated as EuiPageContentBody,
|
||||
} from '@elastic/eui';
|
||||
|
||||
interface StepTwoProps {
|
||||
guidedOnboarding: GuidedOnboardingPluginStart;
|
||||
}
|
||||
|
||||
export const StepTwo = (props: StepTwoProps) => {
|
||||
const {
|
||||
guidedOnboarding: { guidedOnboardingApi },
|
||||
} = props;
|
||||
const { search } = useLocation();
|
||||
const history = useHistory();
|
||||
|
||||
const query = React.useMemo(() => new URLSearchParams(search), [search]);
|
||||
useEffect(() => {
|
||||
if (query.get('showTour') === 'true') {
|
||||
setIsTourStepOpen(true);
|
||||
}
|
||||
}, [query]);
|
||||
|
||||
const [isTourStepOpen, setIsTourStepOpen] = useState<boolean>(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<EuiPageContentHeader>
|
||||
<EuiTitle>
|
||||
<h2>
|
||||
<FormattedMessage
|
||||
id="guidedOnboardingExample.stepTwo.title"
|
||||
defaultMessage="Example step 2"
|
||||
/>
|
||||
</h2>
|
||||
</EuiTitle>
|
||||
</EuiPageContentHeader>
|
||||
<EuiPageContentBody>
|
||||
<EuiText>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="guidedOnboardingExample.guidesSelection.stepTwo.explanation"
|
||||
defaultMessage="The EUI tour on this page is displayed, when a url param 'showTour' is set to 'true'."
|
||||
/>
|
||||
</p>
|
||||
</EuiText>
|
||||
<EuiSpacer />
|
||||
<EuiTourStep
|
||||
content={
|
||||
<EuiText>
|
||||
<p>Click this button to complete step 2.</p>
|
||||
</EuiText>
|
||||
}
|
||||
isStepOpen={isTourStepOpen}
|
||||
minWidth={300}
|
||||
onFinish={() => {
|
||||
history.push('/stepTwo');
|
||||
query.set('showTour', 'false');
|
||||
setIsTourStepOpen(false);
|
||||
}}
|
||||
step={1}
|
||||
stepsTotal={1}
|
||||
title="Step Add data"
|
||||
anchorPosition="rightUp"
|
||||
>
|
||||
<EuiButton
|
||||
onClick={async () => {
|
||||
await guidedOnboardingApi?.updateGuideState({
|
||||
activeGuide: 'search',
|
||||
activeStep: 'optimize',
|
||||
});
|
||||
}}
|
||||
>
|
||||
Complete step 2
|
||||
</EuiButton>
|
||||
</EuiTourStep>
|
||||
</EuiPageContentBody>
|
||||
</>
|
||||
);
|
||||
};
|
19
examples/guided_onboarding_example/public/index.ts
Executable file
19
examples/guided_onboarding_example/public/index.ts
Executable file
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { GuidedOnboardingExamplePlugin } from './plugin';
|
||||
|
||||
// This exports static code and TypeScript types,
|
||||
// as well as, Kibana Platform `plugin()` initializer.
|
||||
export function plugin() {
|
||||
return new GuidedOnboardingExamplePlugin();
|
||||
}
|
||||
export type {
|
||||
GuidedOnboardingExamplePluginSetup,
|
||||
GuidedOnboardingExamplePluginStart,
|
||||
} from './types';
|
43
examples/guided_onboarding_example/public/plugin.ts
Executable file
43
examples/guided_onboarding_example/public/plugin.ts
Executable file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { AppMountParameters, CoreSetup, CoreStart, Plugin } from '@kbn/core/public';
|
||||
import {
|
||||
GuidedOnboardingExamplePluginSetup,
|
||||
GuidedOnboardingExamplePluginStart,
|
||||
AppPluginStartDependencies,
|
||||
} from './types';
|
||||
import { PLUGIN_NAME } from '../common';
|
||||
|
||||
export class GuidedOnboardingExamplePlugin
|
||||
implements Plugin<GuidedOnboardingExamplePluginSetup, GuidedOnboardingExamplePluginStart>
|
||||
{
|
||||
public setup(core: CoreSetup): GuidedOnboardingExamplePluginSetup {
|
||||
// Register an application into the side navigation menu
|
||||
core.application.register({
|
||||
id: 'guidedOnboardingExample',
|
||||
title: PLUGIN_NAME,
|
||||
async mount(params: AppMountParameters) {
|
||||
// Load application bundle
|
||||
const { renderApp } = await import('./application');
|
||||
// Get start services as specified in kibana.json
|
||||
const [coreStart, depsStart] = await core.getStartServices();
|
||||
// Render the application
|
||||
return renderApp(coreStart, depsStart as AppPluginStartDependencies, params);
|
||||
},
|
||||
});
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
public start(core: CoreStart): GuidedOnboardingExamplePluginStart {
|
||||
return {};
|
||||
}
|
||||
|
||||
public stop() {}
|
||||
}
|
21
examples/guided_onboarding_example/public/types.ts
Executable file
21
examples/guided_onboarding_example/public/types.ts
Executable file
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { NavigationPublicPluginStart } from '@kbn/navigation-plugin/public';
|
||||
import { GuidedOnboardingPluginStart } from '@kbn/guided-onboarding-plugin/public/types';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||
export interface GuidedOnboardingExamplePluginSetup {}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||
export interface GuidedOnboardingExamplePluginStart {}
|
||||
|
||||
export interface AppPluginStartDependencies {
|
||||
navigation: NavigationPublicPluginStart;
|
||||
guidedOnboarding: GuidedOnboardingPluginStart;
|
||||
}
|
24
examples/guided_onboarding_example/tsconfig.json
Normal file
24
examples/guided_onboarding_example/tsconfig.json
Normal file
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./target/types",
|
||||
"emitDeclarationOnly": true,
|
||||
"declaration": true,
|
||||
"declarationMap": true
|
||||
},
|
||||
"include": [
|
||||
"__jest__/**/*",
|
||||
"common/**/*",
|
||||
"public/**/*",
|
||||
"server/**/*",
|
||||
"../../typings/**/*",
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
"path": "../../src/core/tsconfig.json"
|
||||
},
|
||||
{
|
||||
"path": "../../src/plugins/guided_onboarding/tsconfig.json"
|
||||
},
|
||||
]
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue