[Home] APM tutorial - show launch app button when APM application is running (#16818) (#17125)

* add launch application to footer, update APM tutorial with applicaton artifacts when APM xpack is enabled

* remove launch and dashboard logic from footer to external component

* return null when url not provided to footer

* make url and label props required

* remove eslint comment

* change dashboard linkLabel
This commit is contained in:
Nathan Reese 2018-03-13 11:15:59 -06:00 committed by GitHub
parent 3f9fee6017
commit 8dc1bc6dad
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 132 additions and 48 deletions

View file

@ -18,7 +18,11 @@ const artifactsSchema = Joi.object({
documentationUrl: Joi.string().required()
}),
// Kibana dashboards created by this product.
dashboards: Joi.array().items(dashboardSchema).required()
dashboards: Joi.array().items(dashboardSchema).required(),
application: Joi.object({
path: Joi.string().required(),
label: Joi.string().required()
}),
});
const instructionSchema = Joi.object({

View file

@ -0,0 +1,43 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`render 1`] = `
<div>
<EuiHorizontalRule
margin="l"
size="full"
/>
<EuiFlexGroup
alignItems="flexEnd"
component="div"
gutterSize="l"
justifyContent="spaceBetween"
responsive={true}
wrap={false}
>
<EuiFlexItem
component="div"
grow={false}
>
<EuiText>
<p>
When all steps are complete, you're ready to explore your data.
</p>
</EuiText>
</EuiFlexItem>
<EuiFlexItem
component="div"
grow={false}
>
<EuiButton
color="primary"
fill={true}
href="/app/myapp"
iconSide="left"
type="button"
>
launch myapp
</EuiButton>
</EuiFlexItem>
</EuiFlexGroup>
</div>
`;

View file

@ -1,54 +1,47 @@
import React from 'react';
import PropTypes from 'prop-types';
import {
KuiLinkButton,
} from 'ui_framework/components';
import {
EuiFlexGroup,
EuiFlexItem,
EuiHorizontalRule,
EuiText,
EuiButton,
} from '@elastic/eui';
export function Footer({ overviewDashboard }) {
if (overviewDashboard) {
return (
<div>
<EuiHorizontalRule />
export function Footer({ url, label }) {
return (
<div>
<EuiHorizontalRule />
<EuiFlexGroup justifyContent="spaceBetween" alignItems="flexEnd">
<EuiFlexGroup justifyContent="spaceBetween" alignItems="flexEnd">
<EuiFlexItem grow={false}>
<EuiText>
<p>
{`When all steps are complete, you're ready to explore your data.`}
</p>
</EuiText>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiText>
<p>
{`When all steps are complete, you're ready to explore your data.`}
</p>
</EuiText>
</EuiFlexItem>
<EuiFlexItem
grow={false}
<EuiFlexItem
grow={false}
>
<EuiButton
fill
href={url}
>
<KuiLinkButton
buttonType="primary"
href={`#/dashboard/${overviewDashboard.id}`}
>
{overviewDashboard.linkLabel}
</KuiLinkButton>
</EuiFlexItem>
{label}
</EuiButton>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexGroup>
</div>
);
}
</div>
);
}
Footer.propTypes = {
overviewDashboard: PropTypes.shape({
id: PropTypes.string.isRequired,
linkLabel: PropTypes.string.isRequired,
})
url: PropTypes.string.isRequired,
label: PropTypes.string.isRequired,
};

View file

@ -0,0 +1,14 @@
import React from 'react';
import { shallow } from 'enzyme';
import {
Footer,
} from './footer';
test('render', () => {
const component = shallow(<Footer
url={'/app/myapp'}
label={'launch myapp'}
/>);
expect(component).toMatchSnapshot();
});

View file

@ -148,14 +148,26 @@ export class Tutorial extends React.Component {
}
renderFooter = () => {
if (_.has(this.state, 'tutorial.artifacts.dashboards')) {
let label;
let url;
if (_.has(this.state, 'tutorial.artifacts.application')) {
label = this.state.tutorial.artifacts.application.label;
url = this.props.addBasePath(this.state.tutorial.artifacts.application.path);
} else if (_.has(this.state, 'tutorial.artifacts.dashboards')) {
const overviewDashboard = this.state.tutorial.artifacts.dashboards.find(dashboard => {
return dashboard.isOverview;
});
if (overviewDashboard) {
label = overviewDashboard.linkLabel;
url = this.props.addBasePath(`/app/kibana#/dashboard/${overviewDashboard.id}`);
}
}
if (url && label) {
return (
<Footer
overviewDashboard={overviewDashboard}
label={label}
url={url}
/>
);
}

View file

@ -3,7 +3,33 @@ import { ON_PREM_INSTRUCTIONS } from './on_prem';
const apmIntro = 'Collect in-depth performance metrics and errors from inside your applications.';
export function apmSpecProvider() {
function isEnabled(config, key) {
try {
return config.get(key);
} catch (err) {
return false;
}
}
export function apmSpecProvider(server) {
const config = server.config();
const artifacts = {
dashboards: [
{
id: '8d3ed660-7828-11e7-8c47-65b845b5cfb3',
linkLabel: 'APM dashboard',
isOverview: true
}
]
};
if (isEnabled(config, 'xpack.apm.ui.enabled')) {
artifacts.application = {
path: '/app/apm',
label: 'Launch APM'
};
}
return {
id: 'apm',
name: 'APM',
@ -14,15 +40,7 @@ export function apmSpecProvider() {
' It allows you to monitor the performance of thousands of applications in real time.' +
' [Learn more]({config.docs.base_url}guide/en/apm/get-started/{config.docs.version}/index.html).',
euiIconType: 'apmApp',
artifacts: {
dashboards: [
{
id: '8d3ed660-7828-11e7-8c47-65b845b5cfb3',
linkLabel: 'APM Services dashboard',
isOverview: true
}
]
},
artifacts: artifacts,
onPrem: ON_PREM_INSTRUCTIONS,
previewImagePath: '/plugins/kibana/home/tutorial_resources/apm/apm_dashboard_transactions.jpg',
};

View file

@ -10,7 +10,7 @@ export function tutorialsMixin(kbnServer, server) {
});
server.decorate('server', 'registerTutorial', (specProvider) => {
const { error, value } = Joi.validate(specProvider(), tutorialSchema);
const { error, value } = Joi.validate(specProvider(server), tutorialSchema);
if (error) {
throw new Error(`Unable to register tutorial spec because its invalid. ${error}`);