mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
* add statusCheck configuration to instructionSetSchema * add status check step to instruction set * track status check state * query elasticsearch for hits * display message when status check completes * clean up * use callout to display status check results * Updated status check * update tutorial snapshot * add jest tests for InstructionSet component * pass function as prop instead of wrapping in new function * refactor checkInstructionSetStatus * update snapshots that broke after rebase * Suggested changes (#24) * update jest test for statusCheckState prop enum * update tutorial snapshots
This commit is contained in:
parent
5db2efdb43
commit
1dae5950af
9 changed files with 1179 additions and 87 deletions
|
@ -25,6 +25,18 @@ const artifactsSchema = Joi.object({
|
|||
}),
|
||||
});
|
||||
|
||||
const statusCheckSchema = Joi.object({
|
||||
title: Joi.string(),
|
||||
text: Joi.string(),
|
||||
btnLabel: Joi.string(),
|
||||
success: Joi.string(),
|
||||
error: Joi.string(),
|
||||
esHitsCheck: Joi.object({
|
||||
index: Joi.string().required(),
|
||||
query: Joi.object().required(),
|
||||
}).required(),
|
||||
});
|
||||
|
||||
const instructionSchema = Joi.object({
|
||||
title: Joi.string(),
|
||||
textPre: Joi.string(),
|
||||
|
@ -40,7 +52,8 @@ const instructionVariantSchema = Joi.object({
|
|||
const instructionSetSchema = Joi.object({
|
||||
title: Joi.string(),
|
||||
// Variants (OSes, languages, etc.) for which tutorial instructions are specified.
|
||||
instructionVariants: Joi.array().items(instructionVariantSchema).required()
|
||||
instructionVariants: Joi.array().items(instructionVariantSchema).required(),
|
||||
statusCheck: statusCheckSchema,
|
||||
});
|
||||
|
||||
const paramSchema = Joi.object({
|
||||
|
|
|
@ -0,0 +1,731 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`render 1`] = `
|
||||
<div
|
||||
className="kuiVerticalRhythmLarge"
|
||||
>
|
||||
<KuiBar
|
||||
className="kuiVerticalRhythm"
|
||||
>
|
||||
<KuiBarSection>
|
||||
<div
|
||||
className="kuiTitle"
|
||||
>
|
||||
title1
|
||||
</div>
|
||||
</KuiBarSection>
|
||||
<KuiBarSection />
|
||||
</KuiBar>
|
||||
<EuiTabs
|
||||
className="kuiVerticalRhythm"
|
||||
>
|
||||
<EuiTab
|
||||
disabled={false}
|
||||
isSelected={true}
|
||||
key="0"
|
||||
onClick={[Function]}
|
||||
>
|
||||
OSX
|
||||
</EuiTab>
|
||||
<EuiTab
|
||||
disabled={false}
|
||||
isSelected={false}
|
||||
key="1"
|
||||
onClick={[Function]}
|
||||
>
|
||||
Windows
|
||||
</EuiTab>
|
||||
</EuiTabs>
|
||||
<EuiSpacer
|
||||
size="m"
|
||||
/>
|
||||
<EuiSteps
|
||||
firstStepNumber={1}
|
||||
headingElement="p"
|
||||
steps={
|
||||
Array [
|
||||
Object {
|
||||
"children": <Instruction
|
||||
commands={
|
||||
Array [
|
||||
"do stuff in command line",
|
||||
]
|
||||
}
|
||||
paramValues={Object {}}
|
||||
replaceTemplateStrings={[Function]}
|
||||
textPost={undefined}
|
||||
textPre={undefined}
|
||||
/>,
|
||||
"key": 0,
|
||||
"title": "step 1",
|
||||
},
|
||||
Object {
|
||||
"children": <Instruction
|
||||
commands={
|
||||
Array [
|
||||
"do more stuff in command line",
|
||||
]
|
||||
}
|
||||
paramValues={Object {}}
|
||||
replaceTemplateStrings={[Function]}
|
||||
textPost={undefined}
|
||||
textPre={undefined}
|
||||
/>,
|
||||
"key": 1,
|
||||
"title": "step 2",
|
||||
},
|
||||
]
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`statusCheckState checking status 1`] = `
|
||||
<div
|
||||
className="kuiVerticalRhythmLarge"
|
||||
>
|
||||
<KuiBar
|
||||
className="kuiVerticalRhythm"
|
||||
>
|
||||
<KuiBarSection>
|
||||
<div
|
||||
className="kuiTitle"
|
||||
>
|
||||
title1
|
||||
</div>
|
||||
</KuiBarSection>
|
||||
<KuiBarSection />
|
||||
</KuiBar>
|
||||
<EuiTabs
|
||||
className="kuiVerticalRhythm"
|
||||
>
|
||||
<EuiTab
|
||||
disabled={false}
|
||||
isSelected={true}
|
||||
key="0"
|
||||
onClick={[Function]}
|
||||
>
|
||||
OSX
|
||||
</EuiTab>
|
||||
<EuiTab
|
||||
disabled={false}
|
||||
isSelected={false}
|
||||
key="1"
|
||||
onClick={[Function]}
|
||||
>
|
||||
Windows
|
||||
</EuiTab>
|
||||
</EuiTabs>
|
||||
<EuiSpacer
|
||||
size="m"
|
||||
/>
|
||||
<EuiSteps
|
||||
firstStepNumber={1}
|
||||
headingElement="p"
|
||||
steps={
|
||||
Array [
|
||||
Object {
|
||||
"children": <Instruction
|
||||
commands={
|
||||
Array [
|
||||
"do stuff in command line",
|
||||
]
|
||||
}
|
||||
paramValues={Object {}}
|
||||
replaceTemplateStrings={[Function]}
|
||||
textPost={undefined}
|
||||
textPre={undefined}
|
||||
/>,
|
||||
"key": 0,
|
||||
"title": "step 1",
|
||||
},
|
||||
Object {
|
||||
"children": <Instruction
|
||||
commands={
|
||||
Array [
|
||||
"do more stuff in command line",
|
||||
]
|
||||
}
|
||||
paramValues={Object {}}
|
||||
replaceTemplateStrings={[Function]}
|
||||
textPost={undefined}
|
||||
textPre={undefined}
|
||||
/>,
|
||||
"key": 1,
|
||||
"title": "step 2",
|
||||
},
|
||||
Object {
|
||||
"children": <UNDEFINED>
|
||||
<EuiFlexGroup
|
||||
alignItems="center"
|
||||
component="div"
|
||||
direction="row"
|
||||
gutterSize="l"
|
||||
justifyContent="spaceBetween"
|
||||
responsive={true}
|
||||
wrap={false}
|
||||
>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={true}
|
||||
>
|
||||
<EuiText
|
||||
grow={true}
|
||||
>
|
||||
<p>
|
||||
custom status check description
|
||||
</p>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={false}
|
||||
>
|
||||
<EuiButton
|
||||
color="primary"
|
||||
fill={false}
|
||||
iconSide="left"
|
||||
isLoading={true}
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
custom btn label
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<EuiSpacer
|
||||
size="s"
|
||||
/>
|
||||
</UNDEFINED>,
|
||||
"key": "checkStatusStep",
|
||||
"status": "incomplete",
|
||||
"title": "custom title",
|
||||
},
|
||||
]
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`statusCheckState failed status check - error 1`] = `
|
||||
<div
|
||||
className="kuiVerticalRhythmLarge"
|
||||
>
|
||||
<KuiBar
|
||||
className="kuiVerticalRhythm"
|
||||
>
|
||||
<KuiBarSection>
|
||||
<div
|
||||
className="kuiTitle"
|
||||
>
|
||||
title1
|
||||
</div>
|
||||
</KuiBarSection>
|
||||
<KuiBarSection />
|
||||
</KuiBar>
|
||||
<EuiTabs
|
||||
className="kuiVerticalRhythm"
|
||||
>
|
||||
<EuiTab
|
||||
disabled={false}
|
||||
isSelected={true}
|
||||
key="0"
|
||||
onClick={[Function]}
|
||||
>
|
||||
OSX
|
||||
</EuiTab>
|
||||
<EuiTab
|
||||
disabled={false}
|
||||
isSelected={false}
|
||||
key="1"
|
||||
onClick={[Function]}
|
||||
>
|
||||
Windows
|
||||
</EuiTab>
|
||||
</EuiTabs>
|
||||
<EuiSpacer
|
||||
size="m"
|
||||
/>
|
||||
<EuiSteps
|
||||
firstStepNumber={1}
|
||||
headingElement="p"
|
||||
steps={
|
||||
Array [
|
||||
Object {
|
||||
"children": <Instruction
|
||||
commands={
|
||||
Array [
|
||||
"do stuff in command line",
|
||||
]
|
||||
}
|
||||
paramValues={Object {}}
|
||||
replaceTemplateStrings={[Function]}
|
||||
textPost={undefined}
|
||||
textPre={undefined}
|
||||
/>,
|
||||
"key": 0,
|
||||
"title": "step 1",
|
||||
},
|
||||
Object {
|
||||
"children": <Instruction
|
||||
commands={
|
||||
Array [
|
||||
"do more stuff in command line",
|
||||
]
|
||||
}
|
||||
paramValues={Object {}}
|
||||
replaceTemplateStrings={[Function]}
|
||||
textPost={undefined}
|
||||
textPre={undefined}
|
||||
/>,
|
||||
"key": 1,
|
||||
"title": "step 2",
|
||||
},
|
||||
Object {
|
||||
"children": <UNDEFINED>
|
||||
<EuiFlexGroup
|
||||
alignItems="center"
|
||||
component="div"
|
||||
direction="row"
|
||||
gutterSize="l"
|
||||
justifyContent="spaceBetween"
|
||||
responsive={true}
|
||||
wrap={false}
|
||||
>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={true}
|
||||
>
|
||||
<EuiText
|
||||
grow={true}
|
||||
>
|
||||
<p>
|
||||
custom status check description
|
||||
</p>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={false}
|
||||
>
|
||||
<EuiButton
|
||||
color="primary"
|
||||
fill={false}
|
||||
iconSide="left"
|
||||
isLoading={false}
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
custom btn label
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<EuiSpacer
|
||||
size="s"
|
||||
/>
|
||||
<EuiCallOut
|
||||
color="warning"
|
||||
size="m"
|
||||
title="custom error msg"
|
||||
/>
|
||||
</UNDEFINED>,
|
||||
"key": "checkStatusStep",
|
||||
"status": "complete",
|
||||
"title": "custom title",
|
||||
},
|
||||
]
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`statusCheckState failed status check - no data 1`] = `
|
||||
<div
|
||||
className="kuiVerticalRhythmLarge"
|
||||
>
|
||||
<KuiBar
|
||||
className="kuiVerticalRhythm"
|
||||
>
|
||||
<KuiBarSection>
|
||||
<div
|
||||
className="kuiTitle"
|
||||
>
|
||||
title1
|
||||
</div>
|
||||
</KuiBarSection>
|
||||
<KuiBarSection />
|
||||
</KuiBar>
|
||||
<EuiTabs
|
||||
className="kuiVerticalRhythm"
|
||||
>
|
||||
<EuiTab
|
||||
disabled={false}
|
||||
isSelected={true}
|
||||
key="0"
|
||||
onClick={[Function]}
|
||||
>
|
||||
OSX
|
||||
</EuiTab>
|
||||
<EuiTab
|
||||
disabled={false}
|
||||
isSelected={false}
|
||||
key="1"
|
||||
onClick={[Function]}
|
||||
>
|
||||
Windows
|
||||
</EuiTab>
|
||||
</EuiTabs>
|
||||
<EuiSpacer
|
||||
size="m"
|
||||
/>
|
||||
<EuiSteps
|
||||
firstStepNumber={1}
|
||||
headingElement="p"
|
||||
steps={
|
||||
Array [
|
||||
Object {
|
||||
"children": <Instruction
|
||||
commands={
|
||||
Array [
|
||||
"do stuff in command line",
|
||||
]
|
||||
}
|
||||
paramValues={Object {}}
|
||||
replaceTemplateStrings={[Function]}
|
||||
textPost={undefined}
|
||||
textPre={undefined}
|
||||
/>,
|
||||
"key": 0,
|
||||
"title": "step 1",
|
||||
},
|
||||
Object {
|
||||
"children": <Instruction
|
||||
commands={
|
||||
Array [
|
||||
"do more stuff in command line",
|
||||
]
|
||||
}
|
||||
paramValues={Object {}}
|
||||
replaceTemplateStrings={[Function]}
|
||||
textPost={undefined}
|
||||
textPre={undefined}
|
||||
/>,
|
||||
"key": 1,
|
||||
"title": "step 2",
|
||||
},
|
||||
Object {
|
||||
"children": <UNDEFINED>
|
||||
<EuiFlexGroup
|
||||
alignItems="center"
|
||||
component="div"
|
||||
direction="row"
|
||||
gutterSize="l"
|
||||
justifyContent="spaceBetween"
|
||||
responsive={true}
|
||||
wrap={false}
|
||||
>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={true}
|
||||
>
|
||||
<EuiText
|
||||
grow={true}
|
||||
>
|
||||
<p>
|
||||
custom status check description
|
||||
</p>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={false}
|
||||
>
|
||||
<EuiButton
|
||||
color="primary"
|
||||
fill={false}
|
||||
iconSide="left"
|
||||
isLoading={false}
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
custom btn label
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<EuiSpacer
|
||||
size="s"
|
||||
/>
|
||||
<EuiCallOut
|
||||
color="warning"
|
||||
size="m"
|
||||
title="custom error msg"
|
||||
/>
|
||||
</UNDEFINED>,
|
||||
"key": "checkStatusStep",
|
||||
"status": "complete",
|
||||
"title": "custom title",
|
||||
},
|
||||
]
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`statusCheckState initial state - no check has been attempted 1`] = `
|
||||
<div
|
||||
className="kuiVerticalRhythmLarge"
|
||||
>
|
||||
<KuiBar
|
||||
className="kuiVerticalRhythm"
|
||||
>
|
||||
<KuiBarSection>
|
||||
<div
|
||||
className="kuiTitle"
|
||||
>
|
||||
title1
|
||||
</div>
|
||||
</KuiBarSection>
|
||||
<KuiBarSection />
|
||||
</KuiBar>
|
||||
<EuiTabs
|
||||
className="kuiVerticalRhythm"
|
||||
>
|
||||
<EuiTab
|
||||
disabled={false}
|
||||
isSelected={true}
|
||||
key="0"
|
||||
onClick={[Function]}
|
||||
>
|
||||
OSX
|
||||
</EuiTab>
|
||||
<EuiTab
|
||||
disabled={false}
|
||||
isSelected={false}
|
||||
key="1"
|
||||
onClick={[Function]}
|
||||
>
|
||||
Windows
|
||||
</EuiTab>
|
||||
</EuiTabs>
|
||||
<EuiSpacer
|
||||
size="m"
|
||||
/>
|
||||
<EuiSteps
|
||||
firstStepNumber={1}
|
||||
headingElement="p"
|
||||
steps={
|
||||
Array [
|
||||
Object {
|
||||
"children": <Instruction
|
||||
commands={
|
||||
Array [
|
||||
"do stuff in command line",
|
||||
]
|
||||
}
|
||||
paramValues={Object {}}
|
||||
replaceTemplateStrings={[Function]}
|
||||
textPost={undefined}
|
||||
textPre={undefined}
|
||||
/>,
|
||||
"key": 0,
|
||||
"title": "step 1",
|
||||
},
|
||||
Object {
|
||||
"children": <Instruction
|
||||
commands={
|
||||
Array [
|
||||
"do more stuff in command line",
|
||||
]
|
||||
}
|
||||
paramValues={Object {}}
|
||||
replaceTemplateStrings={[Function]}
|
||||
textPost={undefined}
|
||||
textPre={undefined}
|
||||
/>,
|
||||
"key": 1,
|
||||
"title": "step 2",
|
||||
},
|
||||
Object {
|
||||
"children": <UNDEFINED>
|
||||
<EuiFlexGroup
|
||||
alignItems="center"
|
||||
component="div"
|
||||
direction="row"
|
||||
gutterSize="l"
|
||||
justifyContent="spaceBetween"
|
||||
responsive={true}
|
||||
wrap={false}
|
||||
>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={true}
|
||||
>
|
||||
<EuiText
|
||||
grow={true}
|
||||
>
|
||||
<p>
|
||||
custom status check description
|
||||
</p>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={false}
|
||||
>
|
||||
<EuiButton
|
||||
color="primary"
|
||||
fill={false}
|
||||
iconSide="left"
|
||||
isLoading={true}
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
custom btn label
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<EuiSpacer
|
||||
size="s"
|
||||
/>
|
||||
</UNDEFINED>,
|
||||
"key": "checkStatusStep",
|
||||
"status": "incomplete",
|
||||
"title": "custom title",
|
||||
},
|
||||
]
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`statusCheckState successful status check 1`] = `
|
||||
<div
|
||||
className="kuiVerticalRhythmLarge"
|
||||
>
|
||||
<KuiBar
|
||||
className="kuiVerticalRhythm"
|
||||
>
|
||||
<KuiBarSection>
|
||||
<div
|
||||
className="kuiTitle"
|
||||
>
|
||||
title1
|
||||
</div>
|
||||
</KuiBarSection>
|
||||
<KuiBarSection />
|
||||
</KuiBar>
|
||||
<EuiTabs
|
||||
className="kuiVerticalRhythm"
|
||||
>
|
||||
<EuiTab
|
||||
disabled={false}
|
||||
isSelected={true}
|
||||
key="0"
|
||||
onClick={[Function]}
|
||||
>
|
||||
OSX
|
||||
</EuiTab>
|
||||
<EuiTab
|
||||
disabled={false}
|
||||
isSelected={false}
|
||||
key="1"
|
||||
onClick={[Function]}
|
||||
>
|
||||
Windows
|
||||
</EuiTab>
|
||||
</EuiTabs>
|
||||
<EuiSpacer
|
||||
size="m"
|
||||
/>
|
||||
<EuiSteps
|
||||
firstStepNumber={1}
|
||||
headingElement="p"
|
||||
steps={
|
||||
Array [
|
||||
Object {
|
||||
"children": <Instruction
|
||||
commands={
|
||||
Array [
|
||||
"do stuff in command line",
|
||||
]
|
||||
}
|
||||
paramValues={Object {}}
|
||||
replaceTemplateStrings={[Function]}
|
||||
textPost={undefined}
|
||||
textPre={undefined}
|
||||
/>,
|
||||
"key": 0,
|
||||
"title": "step 1",
|
||||
},
|
||||
Object {
|
||||
"children": <Instruction
|
||||
commands={
|
||||
Array [
|
||||
"do more stuff in command line",
|
||||
]
|
||||
}
|
||||
paramValues={Object {}}
|
||||
replaceTemplateStrings={[Function]}
|
||||
textPost={undefined}
|
||||
textPre={undefined}
|
||||
/>,
|
||||
"key": 1,
|
||||
"title": "step 2",
|
||||
},
|
||||
Object {
|
||||
"children": <UNDEFINED>
|
||||
<EuiFlexGroup
|
||||
alignItems="center"
|
||||
component="div"
|
||||
direction="row"
|
||||
gutterSize="l"
|
||||
justifyContent="spaceBetween"
|
||||
responsive={true}
|
||||
wrap={false}
|
||||
>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={true}
|
||||
>
|
||||
<EuiText
|
||||
grow={true}
|
||||
>
|
||||
<p>
|
||||
custom status check description
|
||||
</p>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={false}
|
||||
>
|
||||
<EuiButton
|
||||
color="primary"
|
||||
fill={false}
|
||||
iconSide="left"
|
||||
isLoading={false}
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
custom btn label
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<EuiSpacer
|
||||
size="s"
|
||||
/>
|
||||
<EuiCallOut
|
||||
color="success"
|
||||
size="m"
|
||||
title="custom success msg"
|
||||
/>
|
||||
</UNDEFINED>,
|
||||
"key": "checkStatusStep",
|
||||
"status": "complete",
|
||||
"title": "custom title",
|
||||
},
|
||||
]
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
`;
|
|
@ -56,9 +56,11 @@ exports[`isCloudEnabled is false should not render instruction toggle when ON_PR
|
|||
}
|
||||
key="0"
|
||||
offset={1}
|
||||
onStatusCheck={[Function]}
|
||||
paramValues={Object {}}
|
||||
replaceTemplateStrings={[Function]}
|
||||
setParameter={[Function]}
|
||||
statusCheckState="NOT_CHECKED"
|
||||
title="Instruction title"
|
||||
/>
|
||||
</EuiPanel>
|
||||
|
@ -141,9 +143,11 @@ exports[`isCloudEnabled is false should render ON_PREM instructions with instruc
|
|||
}
|
||||
key="0"
|
||||
offset={1}
|
||||
onStatusCheck={[Function]}
|
||||
paramValues={Object {}}
|
||||
replaceTemplateStrings={[Function]}
|
||||
setParameter={[Function]}
|
||||
statusCheckState="NOT_CHECKED"
|
||||
title="Instruction title"
|
||||
/>
|
||||
</EuiPanel>
|
||||
|
@ -208,9 +212,11 @@ exports[`should render ELASTIC_CLOUD instructions when isCloudEnabled is true 1`
|
|||
}
|
||||
key="0"
|
||||
offset={1}
|
||||
onStatusCheck={[Function]}
|
||||
paramValues={Object {}}
|
||||
replaceTemplateStrings={[Function]}
|
||||
setParameter={[Function]}
|
||||
statusCheckState="NOT_CHECKED"
|
||||
title="Instruction title"
|
||||
/>
|
||||
</EuiPanel>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import classNames from 'classnames';
|
||||
import React from 'react';
|
||||
import React, { Fragment } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
KuiBar,
|
||||
|
@ -13,7 +13,13 @@ import {
|
|||
EuiTab,
|
||||
EuiSpacer,
|
||||
EuiSteps,
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiText,
|
||||
EuiButton,
|
||||
EuiCallOut,
|
||||
} from '@elastic/eui';
|
||||
import * as StatusCheckStates from './status_check_states';
|
||||
|
||||
export class InstructionSet extends React.Component {
|
||||
|
||||
|
@ -58,6 +64,72 @@ export class InstructionSet extends React.Component {
|
|||
{tab.name}
|
||||
</EuiTab>
|
||||
));
|
||||
};
|
||||
|
||||
renderStatusCheckMessage() {
|
||||
let message;
|
||||
let color;
|
||||
switch (this.props.statusCheckState) {
|
||||
case StatusCheckStates.NOT_CHECKED:
|
||||
case StatusCheckStates.FETCHING:
|
||||
return null; // Don't show any message while fetching or if you haven't yet checked.
|
||||
case StatusCheckStates.HAS_DATA:
|
||||
message = this.props.statusCheckConfig.success ? this.props.statusCheckConfig.success : 'Success';
|
||||
color = 'success';
|
||||
break;
|
||||
case StatusCheckStates.ERROR:
|
||||
case StatusCheckStates.NO_DATA:
|
||||
message = this.props.statusCheckConfig.error ? this.props.statusCheckConfig.error : 'No data found';
|
||||
color = 'warning';
|
||||
break;
|
||||
}
|
||||
return (
|
||||
<EuiCallOut
|
||||
title={message}
|
||||
color={color}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
renderStatusCheck() {
|
||||
const { statusCheckState, statusCheckConfig, onStatusCheck } = this.props;
|
||||
const checkStatusStep = (
|
||||
<Fragment>
|
||||
<EuiFlexGroup justifyContent="spaceBetween" alignItems="center">
|
||||
<EuiFlexItem>
|
||||
<EuiText>
|
||||
<p>
|
||||
{statusCheckConfig.text}
|
||||
</p>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
|
||||
<EuiFlexItem
|
||||
grow={false}
|
||||
>
|
||||
<EuiButton
|
||||
onClick={onStatusCheck}
|
||||
isLoading={statusCheckState === StatusCheckStates.FETCHING}
|
||||
>
|
||||
{statusCheckConfig.btnLabel || 'Check status'}
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
||||
<EuiSpacer size="s" />
|
||||
|
||||
{this.renderStatusCheckMessage()}
|
||||
</Fragment>
|
||||
);
|
||||
|
||||
const stepStatus = statusCheckState === StatusCheckStates.NOT_CHECKED ||
|
||||
statusCheckState === StatusCheckStates.FETCHING ? 'incomplete' : 'complete';
|
||||
return {
|
||||
title: statusCheckConfig.title || 'Status Check',
|
||||
status: stepStatus,
|
||||
children: checkStatusStep,
|
||||
key: 'checkStatusStep'
|
||||
};
|
||||
}
|
||||
|
||||
renderInstructions = () => {
|
||||
|
@ -85,13 +157,17 @@ export class InstructionSet extends React.Component {
|
|||
};
|
||||
});
|
||||
|
||||
if (this.props.statusCheckConfig) {
|
||||
steps.push(this.renderStatusCheck());
|
||||
}
|
||||
|
||||
return (
|
||||
<EuiSteps
|
||||
steps={steps}
|
||||
firstStepNumber={this.props.offset}
|
||||
/>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
renderHeader = () => {
|
||||
let paramsVisibilityToggle;
|
||||
|
@ -129,7 +205,7 @@ export class InstructionSet extends React.Component {
|
|||
</KuiBarSection>
|
||||
</KuiBar>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
let paramsForm;
|
||||
|
@ -175,9 +251,26 @@ const instructionVariantShape = PropTypes.shape({
|
|||
instructions: PropTypes.arrayOf(instructionShape).isRequired,
|
||||
});
|
||||
|
||||
const statusCheckConfigShape = PropTypes.shape({
|
||||
success: PropTypes.string,
|
||||
error: PropTypes.string,
|
||||
title: PropTypes.string,
|
||||
text: PropTypes.string,
|
||||
btnLabel: PropTypes.string,
|
||||
});
|
||||
|
||||
InstructionSet.propTypes = {
|
||||
title: PropTypes.string.isRequired,
|
||||
instructionVariants: PropTypes.arrayOf(instructionVariantShape).isRequired,
|
||||
statusCheckConfig: statusCheckConfigShape,
|
||||
statusCheckState: PropTypes.oneOf([
|
||||
StatusCheckStates.FETCHING,
|
||||
StatusCheckStates.NOT_CHECKED,
|
||||
StatusCheckStates.HAS_DATA,
|
||||
StatusCheckStates.NO_DATA,
|
||||
StatusCheckStates.ERROR,
|
||||
]),
|
||||
onStatusCheck: PropTypes.func.isRequired,
|
||||
offset: PropTypes.number.isRequired,
|
||||
params: PropTypes.array,
|
||||
paramValues: PropTypes.object.isRequired,
|
||||
|
|
|
@ -0,0 +1,125 @@
|
|||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
import {
|
||||
InstructionSet,
|
||||
} from './instruction_set';
|
||||
import * as StatusCheckStates from './status_check_states';
|
||||
|
||||
const instructions = [
|
||||
{
|
||||
title: 'step 1',
|
||||
commands: [
|
||||
'do stuff in command line',
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'step 2',
|
||||
commands: [
|
||||
'do more stuff in command line',
|
||||
],
|
||||
}
|
||||
];
|
||||
|
||||
const instructionVariants = [
|
||||
{
|
||||
id: 'OSX',
|
||||
instructions: instructions
|
||||
},
|
||||
{
|
||||
id: 'windows',
|
||||
instructions: instructions,
|
||||
}
|
||||
];
|
||||
|
||||
test('render', () => {
|
||||
const component = shallow(<InstructionSet
|
||||
title="title1"
|
||||
instructionVariants={instructionVariants}
|
||||
onStatusCheck={() => {}}
|
||||
offset={1}
|
||||
paramValues={{}}
|
||||
replaceTemplateStrings={() => {}}
|
||||
/>);
|
||||
expect(component).toMatchSnapshot(); // eslint-disable-line
|
||||
});
|
||||
|
||||
describe('statusCheckState', () => {
|
||||
const statusCheckConfig = {
|
||||
success: 'custom success msg',
|
||||
error: 'custom error msg',
|
||||
title: 'custom title',
|
||||
text: 'custom status check description',
|
||||
btnLabel: 'custom btn label',
|
||||
};
|
||||
|
||||
test('initial state - no check has been attempted', () => {
|
||||
const component = shallow(<InstructionSet
|
||||
title="title1"
|
||||
instructionVariants={instructionVariants}
|
||||
onStatusCheck={() => {}}
|
||||
offset={1}
|
||||
paramValues={{}}
|
||||
statusCheckConfig={statusCheckConfig}
|
||||
replaceTemplateStrings={() => {}}
|
||||
statusCheckState={StatusCheckStates.FETCHING}
|
||||
/>);
|
||||
expect(component).toMatchSnapshot(); // eslint-disable-line
|
||||
});
|
||||
|
||||
test('checking status', () => {
|
||||
const component = shallow(<InstructionSet
|
||||
title="title1"
|
||||
instructionVariants={instructionVariants}
|
||||
onStatusCheck={() => {}}
|
||||
offset={1}
|
||||
paramValues={{}}
|
||||
statusCheckConfig={statusCheckConfig}
|
||||
replaceTemplateStrings={() => {}}
|
||||
statusCheckState={StatusCheckStates.FETCHING}
|
||||
/>);
|
||||
expect(component).toMatchSnapshot(); // eslint-disable-line
|
||||
});
|
||||
|
||||
test('failed status check - error', () => {
|
||||
const component = shallow(<InstructionSet
|
||||
title="title1"
|
||||
instructionVariants={instructionVariants}
|
||||
onStatusCheck={() => {}}
|
||||
offset={1}
|
||||
paramValues={{}}
|
||||
statusCheckConfig={statusCheckConfig}
|
||||
replaceTemplateStrings={() => {}}
|
||||
statusCheckState={StatusCheckStates.ERROR}
|
||||
/>);
|
||||
expect(component).toMatchSnapshot(); // eslint-disable-line
|
||||
});
|
||||
|
||||
test('failed status check - no data', () => {
|
||||
const component = shallow(<InstructionSet
|
||||
title="title1"
|
||||
instructionVariants={instructionVariants}
|
||||
onStatusCheck={() => {}}
|
||||
offset={1}
|
||||
paramValues={{}}
|
||||
statusCheckConfig={statusCheckConfig}
|
||||
replaceTemplateStrings={() => {}}
|
||||
statusCheckState={StatusCheckStates.NO_DATA}
|
||||
/>);
|
||||
expect(component).toMatchSnapshot(); // eslint-disable-line
|
||||
});
|
||||
|
||||
test('successful status check', () => {
|
||||
const component = shallow(<InstructionSet
|
||||
title="title1"
|
||||
instructionVariants={instructionVariants}
|
||||
onStatusCheck={() => {}}
|
||||
offset={1}
|
||||
paramValues={{}}
|
||||
statusCheckConfig={statusCheckConfig}
|
||||
replaceTemplateStrings={() => {}}
|
||||
statusCheckState={StatusCheckStates.HAS_DATA}
|
||||
/>);
|
||||
expect(component).toMatchSnapshot(); // eslint-disable-line
|
||||
});
|
||||
});
|
|
@ -0,0 +1,5 @@
|
|||
export const HAS_DATA = 'has_data';
|
||||
export const FETCHING = 'FETCHING';
|
||||
export const NO_DATA = 'NO_DATA';
|
||||
export const NOT_CHECKED = 'NOT_CHECKED';
|
||||
export const ERROR = 'ERROR';
|
|
@ -7,6 +7,7 @@ import { Introduction } from './introduction';
|
|||
import { InstructionSet } from './instruction_set';
|
||||
import { RadioButtonGroup } from './radio_button_group';
|
||||
import { EuiSpacer, EuiPage, EuiPanel, EuiLink, EuiText } from '@elastic/eui';
|
||||
import * as StatusCheckStates from './status_check_states';
|
||||
|
||||
const INSTRUCTIONS_TYPE = {
|
||||
ELASTIC_CLOUD: 'elasticCloud',
|
||||
|
@ -22,6 +23,7 @@ export class Tutorial extends React.Component {
|
|||
this.state = {
|
||||
notFound: false,
|
||||
paramValues: {},
|
||||
statusCheckStates: [],
|
||||
tutorial: null
|
||||
};
|
||||
|
||||
|
@ -51,7 +53,7 @@ export class Tutorial extends React.Component {
|
|||
// eslint-disable-next-line react/no-did-mount-set-state
|
||||
this.setState({
|
||||
tutorial: tutorial
|
||||
}, this.setParamDefaults);
|
||||
}, this.initInstructionsState);
|
||||
} else {
|
||||
// eslint-disable-next-line react/no-did-mount-set-state
|
||||
this.setState({
|
||||
|
@ -75,26 +77,33 @@ export class Tutorial extends React.Component {
|
|||
default:
|
||||
throw new Error(`Unhandled instruction type ${this.state.visibleInstructions}`);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
setParamDefaults = () => {
|
||||
getInstructionSets = () => this.getInstructions().instructionSets;
|
||||
|
||||
initInstructionsState = () => {
|
||||
const instructions = this.getInstructions();
|
||||
|
||||
const paramValues = {};
|
||||
if (instructions.params) {
|
||||
instructions.params.forEach((param => {
|
||||
paramValues[param.id] = param.defaultValue;
|
||||
}));
|
||||
}
|
||||
|
||||
const statusCheckStates = new Array(instructions.instructionSets.length).fill(StatusCheckStates.NOT_CHECKED);
|
||||
|
||||
this.setState({
|
||||
paramValues: paramValues
|
||||
paramValues,
|
||||
statusCheckStates,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
setVisibleInstructions = (instructionsType) => {
|
||||
this.setState({
|
||||
visibleInstructions: instructionsType
|
||||
}, this.setParamDefaults);
|
||||
}
|
||||
}, this.initInstructionsState);
|
||||
};
|
||||
|
||||
setParameter = (paramId, newValue) => {
|
||||
this.setState(previousState => {
|
||||
|
@ -102,15 +111,59 @@ export class Tutorial extends React.Component {
|
|||
paramValues[paramId] = newValue;
|
||||
return { paramValues: paramValues };
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
checkInstructionSetStatus = async (instructionSetIndex) => {
|
||||
const instructionSet = this.getInstructionSets()[instructionSetIndex];
|
||||
const esHitsCheckConfig = _.get(instructionSet, `statusCheck.esHitsCheck`);
|
||||
|
||||
if (esHitsCheckConfig) {
|
||||
const statusCheckState = await this.fetchEsHitsStatus(esHitsCheckConfig);
|
||||
|
||||
this.setState((prevState) => ({
|
||||
statusCheckStates: {
|
||||
...prevState.statusCheckStates,
|
||||
[instructionSetIndex]: statusCheckState,
|
||||
}
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param esHitsCheckConfig
|
||||
* @return {Promise<string>}
|
||||
*/
|
||||
fetchEsHitsStatus = async (esHitsCheckConfig) => {
|
||||
const searchHeader = JSON.stringify({ index: esHitsCheckConfig.index });
|
||||
const searchBody = JSON.stringify({ query: esHitsCheckConfig.query, size: 1 });
|
||||
const response = await fetch(this.props.addBasePath('/elasticsearch/_msearch'), {
|
||||
method: 'post',
|
||||
body: `${searchHeader}\n${searchBody}\n`,
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
'content-type': 'application/x-ndjson',
|
||||
'kbn-xsrf': 'kibana',
|
||||
},
|
||||
credentials: 'same-origin'
|
||||
});
|
||||
|
||||
if (response.status > 300) {
|
||||
return StatusCheckStates.ERROR;
|
||||
}
|
||||
|
||||
const results = await response.json();
|
||||
const numHits = _.get(results, 'responses.[0].hits.hits.length', 0);
|
||||
return numHits === 0 ? StatusCheckStates.NO_DATA : StatusCheckStates.HAS_DATA;
|
||||
};
|
||||
|
||||
onPrem = () => {
|
||||
this.setVisibleInstructions(INSTRUCTIONS_TYPE.ON_PREM);
|
||||
}
|
||||
};
|
||||
|
||||
onPremElasticCloud = () => {
|
||||
this.setVisibleInstructions(INSTRUCTIONS_TYPE.ON_PREM_ELASTIC_CLOUD);
|
||||
}
|
||||
};
|
||||
|
||||
renderInstructionSetsToggle = () => {
|
||||
if (!this.props.isCloudEnabled && this.state.tutorial.onPremElasticCloud) {
|
||||
|
@ -125,17 +178,33 @@ export class Tutorial extends React.Component {
|
|||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
onStatusCheck = (instructionSetIndex) => {
|
||||
this.setState(
|
||||
(prevState) => ({
|
||||
statusCheckStates: {
|
||||
...prevState.statusCheckStates,
|
||||
[instructionSetIndex]: StatusCheckStates.FETCHING,
|
||||
}
|
||||
}),
|
||||
this.checkInstructionSetStatus.bind(null, instructionSetIndex)
|
||||
);
|
||||
};
|
||||
|
||||
renderInstructionSets = (instructions) => {
|
||||
let offset = 1;
|
||||
return instructions.instructionSets.map((instructionSet, index) => {
|
||||
const currentOffset = offset;
|
||||
offset += instructionSet.instructionVariants[0].instructions.length;
|
||||
|
||||
return (
|
||||
<InstructionSet
|
||||
title={instructionSet.title}
|
||||
instructionVariants={instructionSet.instructionVariants}
|
||||
statusCheckConfig={instructionSet.statusCheck}
|
||||
statusCheckState={this.state.statusCheckStates[index]}
|
||||
onStatusCheck={() => { this.onStatusCheck(index); }}
|
||||
offset={currentOffset}
|
||||
params={instructions.params}
|
||||
paramValues={this.state.paramValues}
|
||||
|
@ -145,7 +214,7 @@ export class Tutorial extends React.Component {
|
|||
/>
|
||||
);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
renderFooter = () => {
|
||||
let label;
|
||||
|
@ -171,7 +240,7 @@ export class Tutorial extends React.Component {
|
|||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
let content;
|
||||
|
@ -238,5 +307,5 @@ Tutorial.propTypes = {
|
|||
isCloudEnabled: PropTypes.bool.isRequired,
|
||||
getTutorial: PropTypes.func.isRequired,
|
||||
replaceTemplateStrings: PropTypes.func.isRequired,
|
||||
tutorialId: PropTypes.string.isRequired
|
||||
tutorialId: PropTypes.string.isRequired,
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { TUTORIAL_CATEGORY } from '../../../common/tutorials/tutorial_category';
|
||||
import { ON_PREM_INSTRUCTIONS } from './on_prem';
|
||||
import { onPremInstructions } from './on_prem';
|
||||
import { ELASTIC_CLOUD_INSTRUCTIONS } from './elastic_cloud';
|
||||
|
||||
const apmIntro = 'Collect in-depth performance metrics and errors from inside your applications.';
|
||||
|
@ -42,7 +42,7 @@ export function apmSpecProvider(server) {
|
|||
' [Learn more]({config.docs.base_url}guide/en/apm/get-started/{config.docs.version}/index.html).',
|
||||
euiIconType: 'apmApp',
|
||||
artifacts: artifacts,
|
||||
onPrem: ON_PREM_INSTRUCTIONS,
|
||||
onPrem: onPremInstructions(server),
|
||||
elasticCloud: ELASTIC_CLOUD_INSTRUCTIONS,
|
||||
previewImagePath: '/plugins/kibana/home/tutorial_resources/apm/apm.png',
|
||||
};
|
||||
|
|
|
@ -17,72 +17,122 @@ import {
|
|||
JS_CLIENT_INSTRUCTIONS,
|
||||
} from './apm_client_instructions';
|
||||
|
||||
export const ON_PREM_INSTRUCTIONS = {
|
||||
instructionSets: [
|
||||
{
|
||||
title: 'APM Server',
|
||||
instructionVariants: [
|
||||
{
|
||||
id: INSTRUCTION_VARIANT.OSX,
|
||||
instructions: [
|
||||
DOWNLOAD_SERVER_OSX,
|
||||
IMPORT_DASHBOARD_UNIX,
|
||||
EDIT_CONFIG,
|
||||
START_SERVER_UNIX,
|
||||
],
|
||||
export function onPremInstructions(server) {
|
||||
let apmIndexPattern = 'apm*';
|
||||
try {
|
||||
apmIndexPattern = server.config().get('xpack.apm.indexPattern');
|
||||
} catch (error) {
|
||||
// ignore error when config does not contain 'xpack.apm.indexPattern'.
|
||||
// This is expected when APM plugin is not running.
|
||||
}
|
||||
|
||||
return {
|
||||
instructionSets: [
|
||||
{
|
||||
title: 'APM Server',
|
||||
instructionVariants: [
|
||||
{
|
||||
id: INSTRUCTION_VARIANT.OSX,
|
||||
instructions: [
|
||||
DOWNLOAD_SERVER_OSX,
|
||||
IMPORT_DASHBOARD_UNIX,
|
||||
EDIT_CONFIG,
|
||||
START_SERVER_UNIX,
|
||||
],
|
||||
},
|
||||
{
|
||||
id: INSTRUCTION_VARIANT.DEB,
|
||||
instructions: [
|
||||
DOWNLOAD_SERVER_DEB,
|
||||
IMPORT_DASHBOARD_UNIX,
|
||||
EDIT_CONFIG,
|
||||
START_SERVER_UNIX,
|
||||
],
|
||||
},
|
||||
{
|
||||
id: INSTRUCTION_VARIANT.RPM,
|
||||
instructions: [
|
||||
DOWNLOAD_SERVER_RPM,
|
||||
IMPORT_DASHBOARD_UNIX,
|
||||
EDIT_CONFIG,
|
||||
START_SERVER_UNIX,
|
||||
],
|
||||
},
|
||||
{
|
||||
id: INSTRUCTION_VARIANT.WINDOWS,
|
||||
instructions: WINDOWS_SERVER_INSTRUCTIONS,
|
||||
},
|
||||
],
|
||||
statusCheck: {
|
||||
title: 'APM Server status',
|
||||
text:
|
||||
'Make sure APM Server is running before you start implementing the APM agents.',
|
||||
btnLabel: 'Check APM Server status',
|
||||
success: 'You have correctly setup APM-Server',
|
||||
error: 'APM-Server has still not connected to Elasticsearch',
|
||||
esHitsCheck: {
|
||||
index: apmIndexPattern,
|
||||
query: {
|
||||
bool: {
|
||||
filter: {
|
||||
exists: {
|
||||
field: 'listening',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
id: INSTRUCTION_VARIANT.DEB,
|
||||
instructions: [
|
||||
DOWNLOAD_SERVER_DEB,
|
||||
IMPORT_DASHBOARD_UNIX,
|
||||
EDIT_CONFIG,
|
||||
START_SERVER_UNIX,
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'APM Agents',
|
||||
instructionVariants: [
|
||||
{
|
||||
id: INSTRUCTION_VARIANT.NODE,
|
||||
instructions: NODE_CLIENT_INSTRUCTIONS,
|
||||
},
|
||||
{
|
||||
id: INSTRUCTION_VARIANT.DJANGO,
|
||||
instructions: DJANGO_CLIENT_INSTRUCTIONS,
|
||||
},
|
||||
{
|
||||
id: INSTRUCTION_VARIANT.FLASK,
|
||||
instructions: FLASK_CLIENT_INSTRUCTIONS,
|
||||
},
|
||||
{
|
||||
id: INSTRUCTION_VARIANT.RAILS,
|
||||
instructions: RAILS_CLIENT_INSTRUCTIONS,
|
||||
},
|
||||
{
|
||||
id: INSTRUCTION_VARIANT.RACK,
|
||||
instructions: RACK_CLIENT_INSTRUCTIONS,
|
||||
},
|
||||
{
|
||||
id: INSTRUCTION_VARIANT.JS,
|
||||
instructions: JS_CLIENT_INSTRUCTIONS,
|
||||
},
|
||||
],
|
||||
statusCheck: {
|
||||
title: 'Agent status',
|
||||
text:
|
||||
'Make sure you application is running, and the agents are sending data',
|
||||
btnLabel: 'Check agent status',
|
||||
success: 'Data succesfully received from one or more agents',
|
||||
error: `No data has been received from agents yet`,
|
||||
esHitsCheck: {
|
||||
index: apmIndexPattern,
|
||||
query: {
|
||||
bool: {
|
||||
filter: {
|
||||
exists: {
|
||||
field: 'processor.name',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
id: INSTRUCTION_VARIANT.RPM,
|
||||
instructions: [
|
||||
DOWNLOAD_SERVER_RPM,
|
||||
IMPORT_DASHBOARD_UNIX,
|
||||
EDIT_CONFIG,
|
||||
START_SERVER_UNIX,
|
||||
],
|
||||
},
|
||||
{
|
||||
id: INSTRUCTION_VARIANT.WINDOWS,
|
||||
instructions: WINDOWS_SERVER_INSTRUCTIONS,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'APM Agents',
|
||||
instructionVariants: [
|
||||
{
|
||||
id: INSTRUCTION_VARIANT.NODE,
|
||||
instructions: NODE_CLIENT_INSTRUCTIONS,
|
||||
},
|
||||
{
|
||||
id: INSTRUCTION_VARIANT.DJANGO,
|
||||
instructions: DJANGO_CLIENT_INSTRUCTIONS,
|
||||
},
|
||||
{
|
||||
id: INSTRUCTION_VARIANT.FLASK,
|
||||
instructions: FLASK_CLIENT_INSTRUCTIONS,
|
||||
},
|
||||
{
|
||||
id: INSTRUCTION_VARIANT.RAILS,
|
||||
instructions: RAILS_CLIENT_INSTRUCTIONS,
|
||||
},
|
||||
{
|
||||
id: INSTRUCTION_VARIANT.RACK,
|
||||
instructions: RACK_CLIENT_INSTRUCTIONS,
|
||||
},
|
||||
{
|
||||
id: INSTRUCTION_VARIANT.JS,
|
||||
instructions: JS_CLIENT_INSTRUCTIONS,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue