Skip to content

Commit

Permalink
[HOME] APM tutorial manifest (#16038)
Browse files Browse the repository at this point in the history
* APM tutorial manifest

* add APM card to home page

* remove toogle when onPremElasticCloud instructions are not provided

* add rails instructions

* add rack and js instructions

* do not show tutorials without elastic cloud instructions when isCloudEnabled

* server download instructions

* add flask agent, fix agent links

* clean up APM intro

* add artifacts
  • Loading branch information
nreese authored Jan 17, 2018
1 parent 465bf63 commit 1712ba4
Show file tree
Hide file tree
Showing 15 changed files with 573 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ export const INSTRUCTION_VARIANT = {
WINDOWS: 'windows',
NODE: 'node',
DJANGO: 'django',
FLASK: 'flask'
FLASK: 'flask',
RAILS: 'rails',
RACK: 'rack',
JS: 'js',
};

const DISPLAY_MAP = {
Expand All @@ -18,6 +21,9 @@ const DISPLAY_MAP = {
[INSTRUCTION_VARIANT.NODE]: 'Node.js',
[INSTRUCTION_VARIANT.DJANGO]: 'Django',
[INSTRUCTION_VARIANT.FLASK]: 'Flask',
[INSTRUCTION_VARIANT.RAILS]: 'Ruby on Rails',
[INSTRUCTION_VARIANT.RACK]: 'Rack',
[INSTRUCTION_VARIANT.JS]: 'JS',
};

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export const TUTORIAL_CATEGORY = {
LOGGING: 'logging',
SECURITY: 'security',
METRICS: 'metrics'
METRICS: 'metrics',
OTHER: 'other',
};
4 changes: 2 additions & 2 deletions src/core_plugins/kibana/common/tutorials/tutorial_schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,10 @@ export const tutorialSchema = {
onPrem: instructionsSchema.required(),

// kibana and elastic cluster running in elastic's cloud
elasticCloud: instructionsSchema.required(),
elasticCloud: instructionsSchema,

// kibana running on prem and elastic cluster running in elastic's cloud
onPremElasticCloud: instructionsSchema.required(),
onPremElasticCloud: instructionsSchema,

// Elastic stack artifacts produced by product when it is setup and run.
artifacts: artifactsSchema,
Expand Down
39 changes: 37 additions & 2 deletions src/core_plugins/kibana/public/home/components/home.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import { FeatureCatalogueCategory } from 'ui/registry/feature_catalogue';
import chrome from 'ui/chrome';
const kbnBaseUrl = chrome.getInjected('kbnBaseUrl');

export function Home({ addBasePath, directories }) {
export function Home({ addBasePath, directories, isCloudEnabled }) {

const renderDirectories = (category) => {
return directories
Expand All @@ -54,9 +54,43 @@ export function Home({ addBasePath, directories }) {
width: '250px',
'minWidth': '200px'
};

let apmCard;
if (!isCloudEnabled) {
apmCard = (
<KuiCard style={cardStyle} className="euiPanel">
<KuiCardDescription>
<KuiCardDescriptionTitle>
<img
src={addBasePath('/plugins/kibana/assets/app_APM.svg')}
/>
<p>
APM
</p>
</KuiCardDescriptionTitle>

<KuiCardDescriptionText>
APM automatically collects in-depth performance metrics and errors from inside your applications.
</KuiCardDescriptionText>
</KuiCardDescription>

<KuiCardFooter>
<KuiLinkButton
buttonType="secondary"
href={addBasePath(`${kbnBaseUrl}#/home/tutorial/apm`)}
>
Add APM
</KuiLinkButton>
</KuiCardFooter>
</KuiCard>
);
}
return (
<div className="kuiVerticalRhythm">
<KuiCardGroup>

{apmCard}

<KuiCard style={cardStyle} className="euiPanel">
<KuiCardDescription>
<KuiCardDescriptionTitle>
Expand Down Expand Up @@ -243,5 +277,6 @@ Home.propTypes = {
path: PropTypes.string.isRequired,
showOnHomePage: PropTypes.bool.isRequired,
category: PropTypes.string.isRequired
}))
})),
isCloudEnabled: PropTypes.bool.isRequired,
};
6 changes: 5 additions & 1 deletion src/core_plugins/kibana/public/home/components/home_app.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,14 @@ import chrome from 'ui/chrome';

export function HomeApp({ addBasePath, directories }) {

const isCloudEnabled = chrome.getInjected('isCloudEnabled', false);

const renderTutorialDirectory = (props) => {
return (
<TutorialDirectory
addBasePath={addBasePath}
openTab={props.match.params.tab}
isCloudEnabled={isCloudEnabled}
/>
);
};
Expand All @@ -28,7 +31,7 @@ export function HomeApp({ addBasePath, directories }) {
return (
<Tutorial
addBasePath={addBasePath}
isCloudEnabled={chrome.getInjected('isCloudEnabled', false)}
isCloudEnabled={isCloudEnabled}
getTutorial={getTutorial}
replaceTemplateStrings={replaceTemplateStrings}
tutorialId={props.match.params.id}
Expand Down Expand Up @@ -61,6 +64,7 @@ export function HomeApp({ addBasePath, directories }) {
<Home
addBasePath={addBasePath}
directories={directories}
isCloudEnabled={isCloudEnabled}
/>
</Route>
</Switch>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`should render ELASTIC_CLOUD instructions when isCloudEnabled is true 1`] = `
exports[`isCloudEnabled is false should not render instruction toggle when ON_PREM_ELASTIC_CLOUD instructions are not provided 1`] = `
<EuiPage
className="home"
>
Expand Down Expand Up @@ -48,7 +48,7 @@ exports[`should render ELASTIC_CLOUD instructions when isCloudEnabled is true 1`
"id": "platform id",
"instructions": Array [
Object {
"title": "elasticCloud instructions",
"title": "onPrem instructions",
},
],
},
Expand All @@ -66,7 +66,7 @@ exports[`should render ELASTIC_CLOUD instructions when isCloudEnabled is true 1`
</EuiPage>
`;

exports[`should render ON_PREM instructions with instructions cloud toggle when isCloudEnabled is false 1`] = `
exports[`isCloudEnabled is false should render ON_PREM instructions with instruction toggle 1`] = `
<EuiPage
className="home"
>
Expand Down Expand Up @@ -149,3 +149,69 @@ exports[`should render ON_PREM instructions with instructions cloud toggle when
</div>
</EuiPage>
`;

exports[`should render ELASTIC_CLOUD instructions when isCloudEnabled is true 1`] = `
<EuiPage
className="home"
>
<EuiLink
color="primary"
href="#/home"
type="button"
>
Home
</EuiLink>
/
<EuiLink
color="primary"
href="#/home/tutorial_directory"
type="button"
>
Add Data
</EuiLink>
<EuiSpacer
size="s"
/>
<div>
<Introduction
description="tutorial used to drive jest tests"
title="jest test tutorial"
/>
<EuiSpacer
size="l"
/>
<div
className="text-center"
/>
<EuiSpacer
size="l"
/>
<EuiPanel
grow={true}
hasShadow={false}
paddingSize="l"
>
<InstructionSet
instructionVariants={
Array [
Object {
"id": "platform id",
"instructions": Array [
Object {
"title": "elasticCloud instructions",
},
],
},
]
}
key="0"
offset={1}
paramValues={Object {}}
replaceTemplateStrings={[Function]}
setParameter={[Function]}
title="Instruction title"
/>
</EuiPanel>
</div>
</EuiPage>
`;
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ mustacheWriter.escapedValue = function escapedValue(token, context) {

export function replaceTemplateStrings(text, params = {}) {
const variables = {
// '{' and '}' can not be used in template since they are used as template tags.
// Must use '{curlyOpen}'' and '{curlyClose}'
curlyOpen: '{',
curlyClose: '}',
config: {
cloud: {
id: chrome.getInjected('cloudId')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ export class Tutorial extends React.Component {
}

renderInstructionSetsToggle = () => {
if (!this.props.isCloudEnabled) {
if (!this.props.isCloudEnabled && this.state.tutorial.onPremElasticCloud) {
const radioButtons = [
{ onClick: this.onPrem, label: 'On premise', dataTestSubj: 'onPremBtn' },
{ onClick: this.onPremElasticCloud, label: 'Elastic Cloud', dataTestSubj: 'onPremElasticCloudBtn' },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,60 @@ const replaceTemplateStrings = (text) => {
return text;
};

test('should render ON_PREM instructions with instructions cloud toggle when isCloudEnabled is false', () => {
const component = shallow(<Tutorial
addBasePath={addBasePath}
isCloudEnabled={false}
getTutorial={getTutorial}
replaceTemplateStrings={replaceTemplateStrings}
tutorialId={'my_testing_tutorial'}
/>);
loadTutorialPromise.then(() => {
component.update();
expect(component).toMatchSnapshot(); // eslint-disable-line
describe('isCloudEnabled is false', () => {

test('should render ON_PREM instructions with instruction toggle', () => {
const component = shallow(<Tutorial
addBasePath={addBasePath}
isCloudEnabled={false}
getTutorial={getTutorial}
replaceTemplateStrings={replaceTemplateStrings}
tutorialId={'my_testing_tutorial'}
/>);
loadTutorialPromise.then(() => {
component.update();
expect(component).toMatchSnapshot(); // eslint-disable-line
});
});

test('should not render instruction toggle when ON_PREM_ELASTIC_CLOUD instructions are not provided', () => {
const loadBasicTutorialPromise = Promise.resolve({
name: 'jest test tutorial',
longDescription: 'tutorial used to drive jest tests',
elasticCloud: buildInstructionSet('elasticCloud'),
onPrem: buildInstructionSet('onPrem')
});
const getBasicTutorial = () => {
return loadBasicTutorialPromise;
};
const component = shallow(<Tutorial
addBasePath={addBasePath}
isCloudEnabled={false}
getTutorial={getBasicTutorial}
replaceTemplateStrings={replaceTemplateStrings}
tutorialId={'my_testing_tutorial'}
/>);
loadBasicTutorialPromise.then(() => {
component.update();
expect(component).toMatchSnapshot(); // eslint-disable-line
});
});

test('should display ON_PREM_ELASTIC_CLOUD instructions when toggle is clicked', () => {
const component = mount(<Tutorial
addBasePath={addBasePath}
isCloudEnabled={false}
getTutorial={getTutorial}
replaceTemplateStrings={replaceTemplateStrings}
tutorialId={'my_testing_tutorial'}
/>);
loadTutorialPromise.then(() => {
component.update();
findTestSubject(component, 'onPremElasticCloudBtn').simulate('click');
expect(component.state('visibleInstructions')).toBe('onPremElasticCloud');
});
});

});

test('should render ELASTIC_CLOUD instructions when isCloudEnabled is true', () => {
Expand All @@ -70,18 +112,3 @@ test('should render ELASTIC_CLOUD instructions when isCloudEnabled is true', ()
expect(component).toMatchSnapshot(); // eslint-disable-line
});
});

test('should display ON_PREM_ELASTIC_CLOUD instructions when cloud toggle is clicked', () => {
const component = mount(<Tutorial
addBasePath={addBasePath}
isCloudEnabled={false}
getTutorial={getTutorial}
replaceTemplateStrings={replaceTemplateStrings}
tutorialId={'my_testing_tutorial'}
/>);
loadTutorialPromise.then(() => {
component.update();
findTestSubject(component, 'onPremElasticCloudBtn').simulate('click');
expect(component.state('visibleInstructions')).toBe('onPremElasticCloud');
});
});
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import _ from 'lodash';
import React from 'react';
import PropTypes from 'prop-types';
import { Synopsis } from './synopsis';
Expand Down Expand Up @@ -47,7 +48,12 @@ export class TutorialDirectory extends React.Component {
}

async componentWillMount() {
const tutorials = await getTutorials();
let tutorials = await getTutorials();
if (this.props.isCloudEnabled) {
tutorials = tutorials.filter(tutorial => {
return _.has(tutorial, 'elasticCloud');
});
}
tutorials.sort((a, b) => {
return a.name.toLowerCase().localeCompare(b.name.toLowerCase());
});
Expand Down Expand Up @@ -126,5 +132,6 @@ export class TutorialDirectory extends React.Component {

TutorialDirectory.propTypes = {
addBasePath: PropTypes.func.isRequired,
openTab: PropTypes.string
openTab: PropTypes.string,
isCloudEnabled: PropTypes.bool.isRequired,
};
Loading

0 comments on commit 1712ba4

Please sign in to comment.