mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[PipelineViewer] Test PipelineViewer sub-components (#20329)
* Rename config view to PipelineViewer. * Decouple CollapsibleStatement from if/else using props.children. * Add tests for PipelineViewer component. * Test Metric component. * Test CollapsibleStatement component. * Test PluginStatement component. * Test Queue component. * Test StatementListHeading component. * Test StatementSection component. Move StatementList component to dedicated file. * Test StatementList component. * Test Statement component. * Run prettier on edited files.
This commit is contained in:
parent
3b3dc0ba02
commit
da2448f4a2
26 changed files with 1681 additions and 274 deletions
|
@ -0,0 +1,32 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`CollapsibleStatement component renders child components 1`] = `
|
||||
<EuiFlexGroup
|
||||
alignItems="center"
|
||||
className="pipelineViewer__statement"
|
||||
component="div"
|
||||
direction="row"
|
||||
gutterSize="none"
|
||||
justifyContent="flexStart"
|
||||
responsive={false}
|
||||
wrap={false}
|
||||
>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={false}
|
||||
key="statementId"
|
||||
>
|
||||
<EuiButtonIcon
|
||||
aria-label={true}
|
||||
color="text"
|
||||
iconType="arrowDown"
|
||||
onClick={[Function]}
|
||||
size="s"
|
||||
type="button"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<div>
|
||||
child element
|
||||
</div>
|
||||
</EuiFlexGroup>
|
||||
`;
|
|
@ -0,0 +1,36 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Metric component does not render warning badge when no warning present 1`] = `
|
||||
<EuiFlexItem
|
||||
className="pipelineViewer__metricFlexItem"
|
||||
component="div"
|
||||
grow={false}
|
||||
>
|
||||
<EuiText
|
||||
className="pipelineViewer__metric metricClass"
|
||||
color="subdued"
|
||||
grow={true}
|
||||
size="s"
|
||||
>
|
||||
<span>
|
||||
220
|
||||
</span>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
`;
|
||||
|
||||
exports[`Metric component renders warning badge 1`] = `
|
||||
<EuiFlexItem
|
||||
className="pipelineViewer__metricFlexItem"
|
||||
component="div"
|
||||
grow={false}
|
||||
>
|
||||
<EuiBadge
|
||||
className="metricClass"
|
||||
color="warning"
|
||||
iconSide="left"
|
||||
>
|
||||
220
|
||||
</EuiBadge>
|
||||
</EuiFlexItem>
|
||||
`;
|
|
@ -0,0 +1,177 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`PipelineViewer component passes expected props 1`] = `
|
||||
<EuiPage
|
||||
restrictWidth={false}
|
||||
>
|
||||
<EuiPageContent
|
||||
className="pipelineViewer"
|
||||
horizontalPosition="center"
|
||||
panelPaddingSize="l"
|
||||
verticalPosition="center"
|
||||
>
|
||||
<StatementSection
|
||||
detailVertex={null}
|
||||
elements={
|
||||
Array [
|
||||
Object {
|
||||
"depth": 0,
|
||||
"id": "standardInput",
|
||||
"parentId": null,
|
||||
},
|
||||
]
|
||||
}
|
||||
headingText="Inputs"
|
||||
iconType="logstashInput"
|
||||
onShowVertexDetails={[Function]}
|
||||
/>
|
||||
<EuiSpacer
|
||||
size="l"
|
||||
/>
|
||||
<Queue
|
||||
queue={
|
||||
Object {
|
||||
"hasExplicitId": false,
|
||||
"id": "__QUEUE__",
|
||||
"meta": null,
|
||||
"stats": Array [],
|
||||
}
|
||||
}
|
||||
/>
|
||||
<EuiSpacer
|
||||
size="l"
|
||||
/>
|
||||
<StatementSection
|
||||
detailVertex={null}
|
||||
elements={
|
||||
Array [
|
||||
Object {
|
||||
"depth": 0,
|
||||
"id": "mutate",
|
||||
"parentId": null,
|
||||
},
|
||||
]
|
||||
}
|
||||
headingText="Filters"
|
||||
iconType="logstashFilter"
|
||||
onShowVertexDetails={[Function]}
|
||||
/>
|
||||
<EuiSpacer
|
||||
size="l"
|
||||
/>
|
||||
<StatementSection
|
||||
detailVertex={null}
|
||||
elements={
|
||||
Array [
|
||||
Object {
|
||||
"depth": 0,
|
||||
"id": "elasticsearch",
|
||||
"parentId": null,
|
||||
},
|
||||
]
|
||||
}
|
||||
headingText="Outputs"
|
||||
iconType="logstashOutput"
|
||||
onShowVertexDetails={[Function]}
|
||||
/>
|
||||
</EuiPageContent>
|
||||
</EuiPage>
|
||||
`;
|
||||
|
||||
exports[`PipelineViewer component renders DetailDrawer when selected vertex is not null 1`] = `
|
||||
<EuiPage
|
||||
restrictWidth={false}
|
||||
>
|
||||
<EuiPageContent
|
||||
className="pipelineViewer"
|
||||
horizontalPosition="center"
|
||||
panelPaddingSize="l"
|
||||
verticalPosition="center"
|
||||
>
|
||||
<StatementSection
|
||||
detailVertex={
|
||||
Object {
|
||||
"id": "stdin",
|
||||
}
|
||||
}
|
||||
elements={
|
||||
Array [
|
||||
Object {
|
||||
"depth": 0,
|
||||
"id": "standardInput",
|
||||
"parentId": null,
|
||||
},
|
||||
]
|
||||
}
|
||||
headingText="Inputs"
|
||||
iconType="logstashInput"
|
||||
onShowVertexDetails={[Function]}
|
||||
/>
|
||||
<EuiSpacer
|
||||
size="l"
|
||||
/>
|
||||
<Queue
|
||||
queue={
|
||||
Object {
|
||||
"hasExplicitId": false,
|
||||
"id": "__QUEUE__",
|
||||
"meta": null,
|
||||
"stats": Array [],
|
||||
}
|
||||
}
|
||||
/>
|
||||
<EuiSpacer
|
||||
size="l"
|
||||
/>
|
||||
<StatementSection
|
||||
detailVertex={
|
||||
Object {
|
||||
"id": "stdin",
|
||||
}
|
||||
}
|
||||
elements={
|
||||
Array [
|
||||
Object {
|
||||
"depth": 0,
|
||||
"id": "mutate",
|
||||
"parentId": null,
|
||||
},
|
||||
]
|
||||
}
|
||||
headingText="Filters"
|
||||
iconType="logstashFilter"
|
||||
onShowVertexDetails={[Function]}
|
||||
/>
|
||||
<EuiSpacer
|
||||
size="l"
|
||||
/>
|
||||
<StatementSection
|
||||
detailVertex={
|
||||
Object {
|
||||
"id": "stdin",
|
||||
}
|
||||
}
|
||||
elements={
|
||||
Array [
|
||||
Object {
|
||||
"depth": 0,
|
||||
"id": "elasticsearch",
|
||||
"parentId": null,
|
||||
},
|
||||
]
|
||||
}
|
||||
headingText="Outputs"
|
||||
iconType="logstashOutput"
|
||||
onShowVertexDetails={[Function]}
|
||||
/>
|
||||
<DetailDrawer
|
||||
onHide={[Function]}
|
||||
vertex={
|
||||
Object {
|
||||
"id": "stdin",
|
||||
}
|
||||
}
|
||||
/>
|
||||
</EuiPageContent>
|
||||
</EuiPage>
|
||||
`;
|
|
@ -0,0 +1,429 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`PluginStatement component adds warning highlight for cpu time 1`] = `
|
||||
<EuiFlexGroup
|
||||
alignItems="center"
|
||||
className="pipelineViewer__statement"
|
||||
component="div"
|
||||
direction="row"
|
||||
gutterSize="none"
|
||||
justifyContent="spaceBetween"
|
||||
responsive={true}
|
||||
wrap={false}
|
||||
>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={false}
|
||||
>
|
||||
<EuiFlexGroup
|
||||
alignItems="center"
|
||||
component="div"
|
||||
direction="row"
|
||||
gutterSize="xs"
|
||||
justifyContent="flexStart"
|
||||
responsive={false}
|
||||
wrap={false}
|
||||
>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={false}
|
||||
>
|
||||
<EuiButtonEmpty
|
||||
className="pipelineViewer__plugin"
|
||||
color="primary"
|
||||
flush="left"
|
||||
iconSide="left"
|
||||
iconType="dot"
|
||||
onClick={[Function]}
|
||||
size="xs"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
mutate
|
||||
</span>
|
||||
</EuiButtonEmpty>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={false}
|
||||
>
|
||||
<EuiBadge
|
||||
color="default"
|
||||
iconSide="left"
|
||||
onClick={[Function]}
|
||||
onClickAriaLabel="View details"
|
||||
>
|
||||
mutatePlugin
|
||||
</EuiBadge>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={false}
|
||||
>
|
||||
<EuiFlexGroup
|
||||
alignItems="stretch"
|
||||
component="div"
|
||||
direction="row"
|
||||
gutterSize="s"
|
||||
justifyContent="flexStart"
|
||||
responsive={true}
|
||||
wrap={false}
|
||||
>
|
||||
<Metric
|
||||
className="pipelineViewer__metric--cpuTime"
|
||||
key="cpuMetric"
|
||||
value="25%"
|
||||
warning={true}
|
||||
/>
|
||||
<Metric
|
||||
className="pipelineViewer__metric--eventMillis"
|
||||
key="eventMillis"
|
||||
value="100 ms/e"
|
||||
warning={false}
|
||||
/>
|
||||
<Metric
|
||||
className="pipelineViewer__metric--events"
|
||||
key="eventsReceived"
|
||||
value="120 e/s received"
|
||||
/>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
`;
|
||||
|
||||
exports[`PluginStatement component adds warning highlight for event millis 1`] = `
|
||||
<EuiFlexGroup
|
||||
alignItems="center"
|
||||
className="pipelineViewer__statement"
|
||||
component="div"
|
||||
direction="row"
|
||||
gutterSize="none"
|
||||
justifyContent="spaceBetween"
|
||||
responsive={true}
|
||||
wrap={false}
|
||||
>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={false}
|
||||
>
|
||||
<EuiFlexGroup
|
||||
alignItems="center"
|
||||
component="div"
|
||||
direction="row"
|
||||
gutterSize="xs"
|
||||
justifyContent="flexStart"
|
||||
responsive={false}
|
||||
wrap={false}
|
||||
>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={false}
|
||||
>
|
||||
<EuiButtonEmpty
|
||||
className="pipelineViewer__plugin"
|
||||
color="primary"
|
||||
flush="left"
|
||||
iconSide="left"
|
||||
iconType="dot"
|
||||
onClick={[Function]}
|
||||
size="xs"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
mutate
|
||||
</span>
|
||||
</EuiButtonEmpty>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={false}
|
||||
>
|
||||
<EuiBadge
|
||||
color="default"
|
||||
iconSide="left"
|
||||
onClick={[Function]}
|
||||
onClickAriaLabel="View details"
|
||||
>
|
||||
mutatePlugin
|
||||
</EuiBadge>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={false}
|
||||
>
|
||||
<EuiFlexGroup
|
||||
alignItems="stretch"
|
||||
component="div"
|
||||
direction="row"
|
||||
gutterSize="s"
|
||||
justifyContent="flexStart"
|
||||
responsive={true}
|
||||
wrap={false}
|
||||
>
|
||||
<Metric
|
||||
className="pipelineViewer__metric--cpuTime"
|
||||
key="cpuMetric"
|
||||
value="25%"
|
||||
warning={false}
|
||||
/>
|
||||
<Metric
|
||||
className="pipelineViewer__metric--eventMillis"
|
||||
key="eventMillis"
|
||||
value="100 ms/e"
|
||||
warning={true}
|
||||
/>
|
||||
<Metric
|
||||
className="pipelineViewer__metric--events"
|
||||
key="eventsReceived"
|
||||
value="120 e/s received"
|
||||
/>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
`;
|
||||
|
||||
exports[`PluginStatement component does not render explicit id field if no id is specified 1`] = `
|
||||
<EuiFlexGroup
|
||||
alignItems="center"
|
||||
className="pipelineViewer__statement"
|
||||
component="div"
|
||||
direction="row"
|
||||
gutterSize="none"
|
||||
justifyContent="spaceBetween"
|
||||
responsive={true}
|
||||
wrap={false}
|
||||
>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={false}
|
||||
>
|
||||
<EuiFlexGroup
|
||||
alignItems="center"
|
||||
component="div"
|
||||
direction="row"
|
||||
gutterSize="xs"
|
||||
justifyContent="flexStart"
|
||||
responsive={false}
|
||||
wrap={false}
|
||||
>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={false}
|
||||
>
|
||||
<EuiButtonEmpty
|
||||
className="pipelineViewer__plugin"
|
||||
color="primary"
|
||||
flush="left"
|
||||
iconSide="left"
|
||||
iconType="dot"
|
||||
onClick={[Function]}
|
||||
size="xs"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
stdin
|
||||
</span>
|
||||
</EuiButtonEmpty>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={false}
|
||||
>
|
||||
<EuiFlexGroup
|
||||
alignItems="stretch"
|
||||
component="div"
|
||||
direction="row"
|
||||
gutterSize="s"
|
||||
justifyContent="flexStart"
|
||||
responsive={true}
|
||||
wrap={false}
|
||||
>
|
||||
<Metric
|
||||
className="pipelineViewer__metric--eventsEmitted"
|
||||
key="eventsEmitted"
|
||||
value="125 e/s emitted"
|
||||
/>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
`;
|
||||
|
||||
exports[`PluginStatement component renders input metrics and explicit id fields 1`] = `
|
||||
<EuiFlexGroup
|
||||
alignItems="center"
|
||||
className="pipelineViewer__statement"
|
||||
component="div"
|
||||
direction="row"
|
||||
gutterSize="none"
|
||||
justifyContent="spaceBetween"
|
||||
responsive={true}
|
||||
wrap={false}
|
||||
>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={false}
|
||||
>
|
||||
<EuiFlexGroup
|
||||
alignItems="center"
|
||||
component="div"
|
||||
direction="row"
|
||||
gutterSize="xs"
|
||||
justifyContent="flexStart"
|
||||
responsive={false}
|
||||
wrap={false}
|
||||
>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={false}
|
||||
>
|
||||
<EuiButtonEmpty
|
||||
className="pipelineViewer__plugin"
|
||||
color="primary"
|
||||
flush="left"
|
||||
iconSide="left"
|
||||
iconType="dot"
|
||||
onClick={[Function]}
|
||||
size="xs"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
stdin
|
||||
</span>
|
||||
</EuiButtonEmpty>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={false}
|
||||
>
|
||||
<EuiBadge
|
||||
color="default"
|
||||
iconSide="left"
|
||||
onClick={[Function]}
|
||||
onClickAriaLabel="View details"
|
||||
>
|
||||
standardInput
|
||||
</EuiBadge>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={false}
|
||||
>
|
||||
<EuiFlexGroup
|
||||
alignItems="stretch"
|
||||
component="div"
|
||||
direction="row"
|
||||
gutterSize="s"
|
||||
justifyContent="flexStart"
|
||||
responsive={true}
|
||||
wrap={false}
|
||||
>
|
||||
<Metric
|
||||
className="pipelineViewer__metric--eventsEmitted"
|
||||
key="eventsEmitted"
|
||||
value="125 e/s emitted"
|
||||
/>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
`;
|
||||
|
||||
exports[`PluginStatement component renders processor statement metrics 1`] = `
|
||||
<EuiFlexGroup
|
||||
alignItems="center"
|
||||
className="pipelineViewer__statement"
|
||||
component="div"
|
||||
direction="row"
|
||||
gutterSize="none"
|
||||
justifyContent="spaceBetween"
|
||||
responsive={true}
|
||||
wrap={false}
|
||||
>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={false}
|
||||
>
|
||||
<EuiFlexGroup
|
||||
alignItems="center"
|
||||
component="div"
|
||||
direction="row"
|
||||
gutterSize="xs"
|
||||
justifyContent="flexStart"
|
||||
responsive={false}
|
||||
wrap={false}
|
||||
>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={false}
|
||||
>
|
||||
<EuiButtonEmpty
|
||||
className="pipelineViewer__plugin"
|
||||
color="primary"
|
||||
flush="left"
|
||||
iconSide="left"
|
||||
iconType="dot"
|
||||
onClick={[Function]}
|
||||
size="xs"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
mutate
|
||||
</span>
|
||||
</EuiButtonEmpty>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={false}
|
||||
>
|
||||
<EuiBadge
|
||||
color="default"
|
||||
iconSide="left"
|
||||
onClick={[Function]}
|
||||
onClickAriaLabel="View details"
|
||||
>
|
||||
mutatePlugin
|
||||
</EuiBadge>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={false}
|
||||
>
|
||||
<EuiFlexGroup
|
||||
alignItems="stretch"
|
||||
component="div"
|
||||
direction="row"
|
||||
gutterSize="s"
|
||||
justifyContent="flexStart"
|
||||
responsive={true}
|
||||
wrap={false}
|
||||
>
|
||||
<Metric
|
||||
className="pipelineViewer__metric--cpuTime"
|
||||
key="cpuMetric"
|
||||
value="25%"
|
||||
warning={false}
|
||||
/>
|
||||
<Metric
|
||||
className="pipelineViewer__metric--eventMillis"
|
||||
key="eventMillis"
|
||||
value="100 ms/e"
|
||||
warning={false}
|
||||
/>
|
||||
<Metric
|
||||
className="pipelineViewer__metric--events"
|
||||
key="eventsReceived"
|
||||
value="120 e/s received"
|
||||
/>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
`;
|
|
@ -0,0 +1,19 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Queue component renders default elements 1`] = `
|
||||
<div>
|
||||
<StatementListHeading
|
||||
iconType="logstashQueue"
|
||||
title="Queue"
|
||||
/>
|
||||
<EuiSpacer
|
||||
size="s"
|
||||
/>
|
||||
<EuiText
|
||||
className="pipelineViewer__queueMessage"
|
||||
grow={true}
|
||||
>
|
||||
Queue metrics not available
|
||||
</EuiText>
|
||||
</div>
|
||||
`;
|
|
@ -0,0 +1,164 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Statement component renders a CollapsibleStatement with else body for non-IfElement 1`] = `
|
||||
<li
|
||||
className="pipelineViewer__listItem"
|
||||
>
|
||||
<div
|
||||
className="pipelineViewer__spaceContainer"
|
||||
/>
|
||||
<CollapsibleStatement
|
||||
collapse={[MockFunction]}
|
||||
expand={[MockFunction]}
|
||||
id="mutate2"
|
||||
isCollapsed={false}
|
||||
>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={false}
|
||||
key="statementName"
|
||||
>
|
||||
<EuiButtonEmpty
|
||||
color="text"
|
||||
flush="left"
|
||||
iconSide="left"
|
||||
onClick={[Function]}
|
||||
size="xs"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
className="pipelineViewer__conditional"
|
||||
>
|
||||
else
|
||||
</span>
|
||||
</EuiButtonEmpty>
|
||||
</EuiFlexItem>
|
||||
</CollapsibleStatement>
|
||||
</li>
|
||||
`;
|
||||
|
||||
exports[`Statement component renders a CollapsibleStatement with if body for branch model 1`] = `
|
||||
<li
|
||||
className="pipelineViewer__listItem"
|
||||
>
|
||||
<div
|
||||
className="pipelineViewer__spaceContainer"
|
||||
/>
|
||||
<CollapsibleStatement
|
||||
collapse={[MockFunction]}
|
||||
expand={[MockFunction]}
|
||||
id="ifStatement"
|
||||
isCollapsed={false}
|
||||
>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={false}
|
||||
key="statementName"
|
||||
>
|
||||
<EuiButtonEmpty
|
||||
color="text"
|
||||
flush="left"
|
||||
iconSide="left"
|
||||
onClick={[Function]}
|
||||
size="xs"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
className="pipelineViewer__conditional"
|
||||
>
|
||||
if
|
||||
</span>
|
||||
</EuiButtonEmpty>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={false}
|
||||
key="ifContent"
|
||||
>
|
||||
<EuiCodeBlock
|
||||
fontSize="s"
|
||||
paddingSize="none"
|
||||
transparentBackground={true}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</CollapsibleStatement>
|
||||
</li>
|
||||
`;
|
||||
|
||||
exports[`Statement component renders a PluginStatement component for plugin model 1`] = `
|
||||
<li
|
||||
className="pipelineViewer__listItem"
|
||||
>
|
||||
<div
|
||||
className="pipelineViewer__spaceContainer"
|
||||
/>
|
||||
<PluginStatement
|
||||
onShowVertexDetails={[MockFunction]}
|
||||
statement={
|
||||
PluginStatement {
|
||||
"hasExplicitId": true,
|
||||
"id": "mutate2",
|
||||
"meta": null,
|
||||
"name": "mutate",
|
||||
"pluginType": "filter",
|
||||
"stats": Array [],
|
||||
"vertex": Object {
|
||||
"hasExplicitId": true,
|
||||
"id": "mutate2",
|
||||
"latestEventsPerSecond": 23,
|
||||
"meta": null,
|
||||
"name": "mutate",
|
||||
"pluginType": "filter",
|
||||
"stats": Array [],
|
||||
},
|
||||
}
|
||||
}
|
||||
/>
|
||||
</li>
|
||||
`;
|
||||
|
||||
exports[`Statement component renders spacers for element with depth > 0 1`] = `
|
||||
<li
|
||||
className="pipelineViewer__listItem"
|
||||
>
|
||||
<div
|
||||
className="pipelineViewer__spaceContainer"
|
||||
>
|
||||
<div
|
||||
className="pipelineViewer__spacer"
|
||||
key="spacer_0"
|
||||
/>
|
||||
<div
|
||||
className="pipelineViewer__spacer"
|
||||
key="spacer_1"
|
||||
/>
|
||||
</div>
|
||||
<CollapsibleStatement
|
||||
collapse={[MockFunction]}
|
||||
expand={[MockFunction]}
|
||||
id="mutate2"
|
||||
isCollapsed={false}
|
||||
>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={false}
|
||||
key="statementName"
|
||||
>
|
||||
<EuiButtonEmpty
|
||||
color="text"
|
||||
flush="left"
|
||||
iconSide="left"
|
||||
onClick={[Function]}
|
||||
size="xs"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
className="pipelineViewer__conditional"
|
||||
>
|
||||
else
|
||||
</span>
|
||||
</EuiButtonEmpty>
|
||||
</EuiFlexItem>
|
||||
</CollapsibleStatement>
|
||||
</li>
|
||||
`;
|
|
@ -0,0 +1,36 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`StatementList renders nested elements as expected 1`] = `
|
||||
<ul
|
||||
className="pipelineViewer__list"
|
||||
>
|
||||
<Statement
|
||||
collapse={[Function]}
|
||||
element={
|
||||
Object {
|
||||
"depth": 0,
|
||||
"id": "mutateIf",
|
||||
"parentId": null,
|
||||
}
|
||||
}
|
||||
expand={[Function]}
|
||||
isCollapsed={false}
|
||||
key="mutateIf"
|
||||
onShowVertexDetails={[MockFunction]}
|
||||
/>
|
||||
<Statement
|
||||
collapse={[Function]}
|
||||
element={
|
||||
Object {
|
||||
"depth": 1,
|
||||
"id": "mutate",
|
||||
"parentId": "mutateIf",
|
||||
}
|
||||
}
|
||||
expand={[Function]}
|
||||
isCollapsed={false}
|
||||
key="mutate"
|
||||
onShowVertexDetails={[MockFunction]}
|
||||
/>
|
||||
</ul>
|
||||
`;
|
|
@ -0,0 +1,35 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`StatementListHeading component renders title and icon type 1`] = `
|
||||
<EuiFlexGroup
|
||||
alignItems="baseline"
|
||||
component="div"
|
||||
direction="row"
|
||||
gutterSize="s"
|
||||
justifyContent="flexStart"
|
||||
responsive={false}
|
||||
wrap={false}
|
||||
>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={false}
|
||||
>
|
||||
<EuiIcon
|
||||
size="m"
|
||||
type="logstashInput"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={false}
|
||||
>
|
||||
<EuiTitle
|
||||
size="s"
|
||||
>
|
||||
<h4>
|
||||
Filters
|
||||
</h4>
|
||||
</EuiTitle>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
`;
|
|
@ -0,0 +1,28 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`StatementSection component renders heading text, correct icon type, and elements for StatementSection 1`] = `
|
||||
<div>
|
||||
<StatementListHeading
|
||||
iconType="logstashInput"
|
||||
title="Inputs"
|
||||
/>
|
||||
<EuiSpacer
|
||||
size="s"
|
||||
/>
|
||||
<StatementList
|
||||
elements={
|
||||
Array [
|
||||
Object {
|
||||
"id": "standardInput",
|
||||
"parentId": null,
|
||||
},
|
||||
Object {
|
||||
"id": "fileInput",
|
||||
"parentId": null,
|
||||
},
|
||||
]
|
||||
}
|
||||
onShowVertexDetails={[MockFunction]}
|
||||
/>
|
||||
</div>
|
||||
`;
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { CollapsibleStatement } from '../collapsible_statement';
|
||||
import { shallow } from 'enzyme';
|
||||
import { EuiButtonIcon } from '@elastic/eui';
|
||||
|
||||
describe('CollapsibleStatement component', () => {
|
||||
let props;
|
||||
let collapse;
|
||||
let expand;
|
||||
|
||||
beforeEach(() => {
|
||||
collapse = jest.fn();
|
||||
expand = jest.fn();
|
||||
props = {
|
||||
collapse,
|
||||
expand,
|
||||
id: 'statementId',
|
||||
isCollapsed: false,
|
||||
};
|
||||
});
|
||||
|
||||
it('renders child components', () => {
|
||||
const child = <div>child element</div>;
|
||||
|
||||
const wrapper = shallow(
|
||||
<CollapsibleStatement {...props}>{child}</CollapsibleStatement>
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('calls collapse if component is expanded', () => {
|
||||
const wrapper = shallow(<CollapsibleStatement {...props} />);
|
||||
|
||||
wrapper.find(EuiButtonIcon).simulate('click');
|
||||
expect(collapse).toHaveBeenCalledTimes(1);
|
||||
expect(collapse).toHaveBeenCalledWith('statementId');
|
||||
});
|
||||
|
||||
it('calls expand if component is collapsed', () => {
|
||||
props.isCollapsed = true;
|
||||
const wrapper = shallow(<CollapsibleStatement {...props} />);
|
||||
|
||||
wrapper.find(EuiButtonIcon).simulate('click');
|
||||
expect(expand).toHaveBeenCalledTimes(1);
|
||||
expect(expand).toHaveBeenCalledWith('statementId');
|
||||
});
|
||||
});
|
|
@ -19,15 +19,10 @@ describe('DetailDrawer component', () => {
|
|||
|
||||
test('shows vertex title', () => {
|
||||
const vertex = {
|
||||
title: 'grok'
|
||||
title: 'grok',
|
||||
};
|
||||
|
||||
const component = (
|
||||
<DetailDrawer
|
||||
vertex={vertex}
|
||||
onHide={onHide}
|
||||
/>
|
||||
);
|
||||
const component = <DetailDrawer vertex={vertex} onHide={onHide} />;
|
||||
const renderedComponent = shallow(component);
|
||||
expect(renderedComponent).toMatchSnapshot();
|
||||
});
|
||||
|
@ -43,46 +38,34 @@ describe('DetailDrawer component', () => {
|
|||
id: 'parse_apache_logline',
|
||||
stats: {
|
||||
events_in: {
|
||||
data: [
|
||||
[ 1516131120000, 200 ],
|
||||
[ 1516131180000, 203 ]
|
||||
],
|
||||
data: [[1516131120000, 200], [1516131180000, 203]],
|
||||
timeRange: {
|
||||
min: 1516131138639,
|
||||
max: 1516135440463
|
||||
}
|
||||
max: 1516135440463,
|
||||
},
|
||||
},
|
||||
events_out: {
|
||||
data: [
|
||||
[ 1516131120000, 199 ],
|
||||
[ 1516131180000, 200 ]
|
||||
],
|
||||
data: [[1516131120000, 199], [1516131180000, 200]],
|
||||
timeRange: {
|
||||
min: 1516131138639,
|
||||
max: 1516135440463
|
||||
}
|
||||
max: 1516135440463,
|
||||
},
|
||||
},
|
||||
millis_per_event: {
|
||||
data: [
|
||||
[ 1516131120000, 0.21 ],
|
||||
[ 1516131180000, 0.23 ]
|
||||
],
|
||||
data: [[1516131120000, 0.21], [1516131180000, 0.23]],
|
||||
timeRange: {
|
||||
min: 1516131138639,
|
||||
max: 1516135440463
|
||||
}
|
||||
}
|
||||
max: 1516135440463,
|
||||
},
|
||||
},
|
||||
},
|
||||
eventsPerSecond: {
|
||||
data: [
|
||||
[ 1516131120000, 32 ],
|
||||
[ 1516131180000, 36 ]
|
||||
],
|
||||
data: [[1516131120000, 32], [1516131180000, 36]],
|
||||
timeRange: {
|
||||
min: 1516131138639,
|
||||
max: 1516135440463
|
||||
}
|
||||
}
|
||||
max: 1516135440463,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const component = (
|
||||
|
@ -107,46 +90,34 @@ describe('DetailDrawer component', () => {
|
|||
id: 'foobarbazqux',
|
||||
stats: {
|
||||
events_in: {
|
||||
data: [
|
||||
[ 1516131120000, 200 ],
|
||||
[ 1516131180000, 203 ]
|
||||
],
|
||||
data: [[1516131120000, 200], [1516131180000, 203]],
|
||||
timeRange: {
|
||||
min: 1516131138639,
|
||||
max: 1516135440463
|
||||
}
|
||||
max: 1516135440463,
|
||||
},
|
||||
},
|
||||
events_out: {
|
||||
data: [
|
||||
[ 1516131120000, 199 ],
|
||||
[ 1516131180000, 200 ]
|
||||
],
|
||||
data: [[1516131120000, 199], [1516131180000, 200]],
|
||||
timeRange: {
|
||||
min: 1516131138639,
|
||||
max: 1516135440463
|
||||
}
|
||||
max: 1516135440463,
|
||||
},
|
||||
},
|
||||
millis_per_event: {
|
||||
data: [
|
||||
[ 1516131120000, 0.21 ],
|
||||
[ 1516131180000, 0.23 ]
|
||||
],
|
||||
data: [[1516131120000, 0.21], [1516131180000, 0.23]],
|
||||
timeRange: {
|
||||
min: 1516131138639,
|
||||
max: 1516135440463
|
||||
}
|
||||
}
|
||||
max: 1516135440463,
|
||||
},
|
||||
},
|
||||
},
|
||||
eventsPerSecond: {
|
||||
data: [
|
||||
[ 1516131120000, 32 ],
|
||||
[ 1516131180000, 36 ]
|
||||
],
|
||||
data: [[1516131120000, 32], [1516131180000, 36]],
|
||||
timeRange: {
|
||||
min: 1516131138639,
|
||||
max: 1516135440463
|
||||
}
|
||||
}
|
||||
max: 1516135440463,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const component = (
|
||||
|
@ -167,7 +138,7 @@ describe('DetailDrawer component', () => {
|
|||
const vertex = {
|
||||
title: 'if',
|
||||
typeString: 'if',
|
||||
subtitle: '[type] == "apache_log"'
|
||||
subtitle: '[type] == "apache_log"',
|
||||
};
|
||||
|
||||
const component = (
|
||||
|
@ -186,7 +157,7 @@ describe('DetailDrawer component', () => {
|
|||
test('shows basic info and no stats for queue', () => {
|
||||
const vertex = {
|
||||
title: 'queue',
|
||||
typeString: 'queue'
|
||||
typeString: 'queue',
|
||||
};
|
||||
|
||||
const component = (
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { Metric } from '../metric';
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
describe('Metric component', () => {
|
||||
let metric;
|
||||
|
||||
beforeEach(() => {
|
||||
metric = {
|
||||
className: 'metricClass',
|
||||
warning: true,
|
||||
value: '220',
|
||||
};
|
||||
});
|
||||
|
||||
it('renders warning badge', () => {
|
||||
const wrapper = shallow(<Metric {...metric} />);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('does not render warning badge when no warning present', () => {
|
||||
metric.warning = false;
|
||||
const wrapper = shallow(<Metric {...metric} />);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { PipelineViewer } from '../pipeline_viewer';
|
||||
import { shallow } from 'enzyme';
|
||||
import { get } from 'lodash';
|
||||
|
||||
describe('PipelineViewer component', () => {
|
||||
let pipeline;
|
||||
let component;
|
||||
|
||||
beforeEach(() => {
|
||||
pipeline = {
|
||||
inputs: [
|
||||
{
|
||||
depth: 0,
|
||||
id: 'standardInput',
|
||||
parentId: null,
|
||||
},
|
||||
],
|
||||
filters: [
|
||||
{
|
||||
depth: 0,
|
||||
id: 'mutate',
|
||||
parentId: null,
|
||||
},
|
||||
],
|
||||
outputs: [
|
||||
{
|
||||
depth: 0,
|
||||
id: 'elasticsearch',
|
||||
parentId: null,
|
||||
},
|
||||
],
|
||||
queue: {
|
||||
id: '__QUEUE__',
|
||||
hasExplicitId: false,
|
||||
stats: [],
|
||||
meta: null,
|
||||
},
|
||||
};
|
||||
|
||||
component = <PipelineViewer pipeline={pipeline} />;
|
||||
});
|
||||
|
||||
it('passes expected props', () => {
|
||||
const renderedComponent = shallow(component);
|
||||
|
||||
expect(renderedComponent).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('changes selected vertex', () => {
|
||||
const vertex = { id: 'stdin' };
|
||||
|
||||
const instance = shallow(component).instance();
|
||||
instance.onShowVertexDetails(vertex);
|
||||
|
||||
expect(get(instance, 'state.detailDrawer.vertex')).toBe(vertex);
|
||||
});
|
||||
|
||||
it('toggles selected vertex on second pass', () => {
|
||||
const vertex = { id: 'stdin' };
|
||||
|
||||
const instance = shallow(component).instance();
|
||||
instance.onShowVertexDetails(vertex);
|
||||
instance.onShowVertexDetails(vertex);
|
||||
|
||||
expect(get(instance, 'state.detailDrawer.vertex')).toBeNull();
|
||||
});
|
||||
|
||||
it('renders DetailDrawer when selected vertex is not null', () => {
|
||||
const vertex = { id: 'stdin' };
|
||||
|
||||
const wrapper = shallow(component);
|
||||
const instance = wrapper.instance();
|
||||
instance.onShowVertexDetails(vertex);
|
||||
wrapper.update();
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { PluginStatement } from '../plugin_statement';
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
import { EuiButtonEmpty, EuiBadge } from '@elastic/eui';
|
||||
|
||||
describe('PluginStatement component', () => {
|
||||
let props;
|
||||
let onShowVertexDetails;
|
||||
let isSlow;
|
||||
let isTimeConsuming;
|
||||
let processorStatement;
|
||||
|
||||
beforeEach(() => {
|
||||
onShowVertexDetails = jest.fn();
|
||||
props = {
|
||||
statement: {
|
||||
hasExplicitId: true,
|
||||
id: 'standardInput',
|
||||
name: 'stdin',
|
||||
pluginType: 'input',
|
||||
vertex: {
|
||||
latestEventsPerSecond: 125,
|
||||
},
|
||||
},
|
||||
onShowVertexDetails,
|
||||
};
|
||||
|
||||
isSlow = jest.fn().mockImplementation(() => false);
|
||||
isTimeConsuming = jest.fn().mockImplementation(() => false);
|
||||
processorStatement = {
|
||||
hasExplicitId: true,
|
||||
id: 'mutatePlugin',
|
||||
name: 'mutate',
|
||||
pluginType: 'filter',
|
||||
vertex: {
|
||||
latestMillisPerEvent: 100,
|
||||
latestEventsPerSecond: 120,
|
||||
percentOfTotalProcessorTime: 25,
|
||||
isSlow,
|
||||
isTimeConsuming,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const render = props => shallow(<PluginStatement {...props} />);
|
||||
|
||||
it('renders input metrics and explicit id fields', () => {
|
||||
expect(render(props)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('does not render explicit id field if no id is specified', () => {
|
||||
props.statement.id = 'dcbb2c37b4fedd3d7b852b5052f03dw3fbe1545a';
|
||||
props.statement.hasExplicitId = false;
|
||||
expect(render(props)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('renders processor statement metrics', () => {
|
||||
props.statement = processorStatement;
|
||||
expect(render(props)).toMatchSnapshot();
|
||||
expect(isSlow).toHaveBeenCalledTimes(1);
|
||||
expect(isTimeConsuming).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('adds warning highlight for cpu time', () => {
|
||||
props.statement = processorStatement;
|
||||
props.statement.vertex.isTimeConsuming = jest
|
||||
.fn()
|
||||
.mockImplementation(() => true);
|
||||
expect(render(props)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('adds warning highlight for event millis', () => {
|
||||
props.statement = processorStatement;
|
||||
props.statement.vertex.isSlow = jest.fn().mockImplementation(() => true);
|
||||
expect(render(props)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('handles name button click', () => {
|
||||
const { vertex } = props.statement;
|
||||
const wrapper = render(props);
|
||||
wrapper.find(EuiButtonEmpty).simulate('click');
|
||||
|
||||
expect(onShowVertexDetails).toHaveBeenCalledTimes(1);
|
||||
expect(onShowVertexDetails).toHaveBeenCalledWith(vertex);
|
||||
});
|
||||
|
||||
it('handles id badge click', () => {
|
||||
const { vertex } = props.statement;
|
||||
const wrapper = render(props);
|
||||
wrapper.find(EuiBadge).simulate('click');
|
||||
|
||||
expect(onShowVertexDetails).toHaveBeenCalledTimes(1);
|
||||
expect(onShowVertexDetails).toHaveBeenCalledWith(vertex);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { Queue } from '../queue';
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
describe('Queue component', () => {
|
||||
it('renders default elements', () => {
|
||||
expect(shallow(<Queue />)).toMatchSnapshot();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { Statement } from '../statement';
|
||||
import { PluginStatement } from '../../models/pipeline/plugin_statement';
|
||||
import { PluginStatement as PluginStatementComponent } from '../plugin_statement';
|
||||
import { IfElement } from '../../models/list/if_element';
|
||||
import { CollapsibleStatement } from '../collapsible_statement';
|
||||
import { shallow } from 'enzyme';
|
||||
import { EuiButtonEmpty } from '@elastic/eui';
|
||||
|
||||
describe('Statement component', () => {
|
||||
let props;
|
||||
let pluginStatement;
|
||||
let branchElement;
|
||||
let collapse;
|
||||
let expand;
|
||||
let onShowVertexDetails;
|
||||
|
||||
beforeEach(() => {
|
||||
collapse = jest.fn();
|
||||
expand = jest.fn();
|
||||
onShowVertexDetails = jest.fn();
|
||||
props = {
|
||||
collapse,
|
||||
element: {
|
||||
depth: 0,
|
||||
id: 'mutate2',
|
||||
statement: {},
|
||||
},
|
||||
expand,
|
||||
isCollapsed: false,
|
||||
onShowVertexDetails,
|
||||
};
|
||||
pluginStatement = new PluginStatement({
|
||||
hasExplicitId: true,
|
||||
id: 'mutate2',
|
||||
latestEventsPerSecond: 23,
|
||||
meta: null,
|
||||
name: 'mutate',
|
||||
pluginType: 'filter',
|
||||
stats: [],
|
||||
});
|
||||
branchElement = new IfElement(
|
||||
{
|
||||
id: 'ifStatement',
|
||||
name: 'ifStatement',
|
||||
},
|
||||
0,
|
||||
null
|
||||
);
|
||||
});
|
||||
|
||||
it('renders a PluginStatement component for plugin model', () => {
|
||||
props.element.statement = pluginStatement;
|
||||
const wrapper = shallow(<Statement {...props} />);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(wrapper.find(PluginStatementComponent)).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('renders spacers for element with depth > 0', () => {
|
||||
props.element.depth = 2;
|
||||
expect(shallow(<Statement {...props} />)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('renders a CollapsibleStatement with if body for branch model', () => {
|
||||
props.element = branchElement;
|
||||
const wrapper = shallow(<Statement {...props} />);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(wrapper.find(CollapsibleStatement)).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('renders a CollapsibleStatement with else body for non-IfElement', () => {
|
||||
expect(shallow(<Statement {...props} />)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it(`selects the element's vertex when the name is clicked`, () => {
|
||||
props.element = branchElement;
|
||||
const wrapper = shallow(<Statement {...props} />);
|
||||
|
||||
wrapper.find(EuiButtonEmpty).simulate('click');
|
||||
expect(onShowVertexDetails).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { StatementList } from '../statement_list';
|
||||
import { Statement } from '../statement';
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
describe('StatementList', () => {
|
||||
let props;
|
||||
let onShowVertexDetails;
|
||||
|
||||
beforeEach(() => {
|
||||
onShowVertexDetails = jest.fn();
|
||||
props = {
|
||||
elements: [
|
||||
{
|
||||
id: 'mutateIf',
|
||||
parentId: null,
|
||||
depth: 0,
|
||||
},
|
||||
{
|
||||
id: 'mutate',
|
||||
parentId: 'mutateIf',
|
||||
depth: 1,
|
||||
},
|
||||
],
|
||||
onShowVertexDetails,
|
||||
};
|
||||
});
|
||||
|
||||
const render = props => shallow(<StatementList {...props} />);
|
||||
|
||||
it('renders nested elements as expected', () => {
|
||||
const wrapper = render(props);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(wrapper.find(Statement).length).toBe(2);
|
||||
});
|
||||
|
||||
it('renders children elements when parent is collapsed', () => {
|
||||
const wrapper = render(props);
|
||||
const instance = wrapper.instance();
|
||||
instance.collapse('mutateIf');
|
||||
wrapper.update();
|
||||
|
||||
expect(wrapper.find(Statement).length).toBe(1);
|
||||
});
|
||||
|
||||
it('renders children after expanding collapsed elements', () => {
|
||||
const wrapper = render(props);
|
||||
const instance = wrapper.instance();
|
||||
|
||||
instance.collapse('mutateIf');
|
||||
wrapper.update();
|
||||
expect(wrapper.find(Statement).length).toBe(1);
|
||||
|
||||
instance.expand('mutateIf');
|
||||
wrapper.update();
|
||||
expect(wrapper.find(Statement).length).toBe(2);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { StatementListHeading } from '../statement_list_heading';
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
describe('StatementListHeading component', () => {
|
||||
let props;
|
||||
|
||||
beforeEach(() => {
|
||||
props = {
|
||||
iconType: 'logstashInput',
|
||||
title: 'Filters',
|
||||
};
|
||||
});
|
||||
|
||||
it('renders title and icon type', () => {
|
||||
expect(shallow(<StatementListHeading {...props} />)).toMatchSnapshot();
|
||||
});
|
||||
});
|
|
@ -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;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { StatementSection } from '../statement_section';
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
describe('StatementSection component', () => {
|
||||
let props;
|
||||
let onShowVertexDetails;
|
||||
|
||||
beforeEach(() => {
|
||||
onShowVertexDetails = jest.fn();
|
||||
props = {
|
||||
elements: [
|
||||
{
|
||||
id: 'standardInput',
|
||||
parentId: null,
|
||||
},
|
||||
{
|
||||
id: 'fileInput',
|
||||
parentId: null,
|
||||
},
|
||||
],
|
||||
headingText: 'Inputs',
|
||||
iconType: 'logstashInput',
|
||||
onShowVertexDetails,
|
||||
};
|
||||
});
|
||||
|
||||
it('renders heading text, correct icon type, and elements for StatementSection', () => {
|
||||
expect(shallow(<StatementSection {...props} />)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('renders nothing if elements array is empty', () => {
|
||||
props.elements = [];
|
||||
const wrapper = shallow(<StatementSection {...props} />);
|
||||
expect(wrapper.instance()).toBe(null);
|
||||
});
|
||||
});
|
|
@ -7,23 +7,14 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import {
|
||||
EuiButtonIcon,
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem
|
||||
} from '@elastic/eui';
|
||||
import { EuiButtonIcon, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
|
||||
|
||||
function getToggleIconType(isCollapsed) {
|
||||
return isCollapsed ? 'arrowRight' : 'arrowDown';
|
||||
}
|
||||
|
||||
export function CollapsibleStatement(props) {
|
||||
const {
|
||||
collapse,
|
||||
expand,
|
||||
id,
|
||||
isCollapsed
|
||||
} = props;
|
||||
const { collapse, expand, id, isCollapsed } = props;
|
||||
|
||||
const toggleClicked = () => {
|
||||
if (isCollapsed) {
|
||||
|
@ -40,10 +31,7 @@ export function CollapsibleStatement(props) {
|
|||
alignItems="center"
|
||||
className="pipelineViewer__statement"
|
||||
>
|
||||
<EuiFlexItem
|
||||
key={id}
|
||||
grow={false}
|
||||
>
|
||||
<EuiFlexItem key={id} grow={false}>
|
||||
<EuiButtonIcon
|
||||
aria-label
|
||||
color="text"
|
||||
|
|
|
@ -6,19 +6,11 @@
|
|||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
EuiFlexItem,
|
||||
EuiBadge,
|
||||
EuiText,
|
||||
} from '@elastic/eui';
|
||||
import { EuiFlexItem, EuiBadge, EuiText } from '@elastic/eui';
|
||||
import classNames from 'classnames';
|
||||
|
||||
export function Metric({ className, value, warning }) {
|
||||
|
||||
const classes = classNames(
|
||||
'pipelineViewer__metric',
|
||||
className,
|
||||
);
|
||||
export function Metric({ className, warning, value }) {
|
||||
const classes = classNames('pipelineViewer__metric', className);
|
||||
|
||||
let stylizedValue;
|
||||
if (warning) {
|
||||
|
@ -30,17 +22,12 @@ export function Metric({ className, value, warning }) {
|
|||
} else {
|
||||
stylizedValue = (
|
||||
<EuiText size="s" color="subdued" className={classes}>
|
||||
<span>
|
||||
{value}
|
||||
</span>
|
||||
<span>{value}</span>
|
||||
</EuiText>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<EuiFlexItem
|
||||
className="pipelineViewer__metricFlexItem"
|
||||
grow={false}
|
||||
>
|
||||
<EuiFlexItem className="pipelineViewer__metricFlexItem" grow={false}>
|
||||
{stylizedValue}
|
||||
</EuiFlexItem>
|
||||
);
|
||||
|
@ -49,4 +36,5 @@ export function Metric({ className, value, warning }) {
|
|||
Metric.propTypes = {
|
||||
className: PropTypes.string.isRequired,
|
||||
value: PropTypes.string.isRequired,
|
||||
warning: PropTypes.bool,
|
||||
};
|
||||
|
|
|
@ -16,13 +16,13 @@ import { formatMetric } from '../../../../lib/format_number';
|
|||
import { Metric } from './metric';
|
||||
|
||||
function getInputStatementMetrics({ latestEventsPerSecond }) {
|
||||
return [(
|
||||
return [
|
||||
<Metric
|
||||
key="eventsEmitted"
|
||||
className="pipelineViewer__metric--eventsEmitted"
|
||||
value={formatMetric(latestEventsPerSecond, '0.[00]a', 'e/s emitted')}
|
||||
/>
|
||||
)];
|
||||
/>,
|
||||
];
|
||||
}
|
||||
|
||||
function getProcessorStatementMetrics(processorVertex) {
|
||||
|
@ -33,29 +33,28 @@ function getProcessorStatementMetrics(processorVertex) {
|
|||
} = processorVertex;
|
||||
|
||||
return [
|
||||
(
|
||||
<Metric
|
||||
key="cpuMetric"
|
||||
className="pipelineViewer__metric--cpuTime"
|
||||
warning={processorVertex.isTimeConsuming()}
|
||||
value={formatMetric(Math.round(percentOfTotalProcessorTime || 0), '0', '%', { prependSpace: false })}
|
||||
/>
|
||||
),
|
||||
(
|
||||
<Metric
|
||||
key="eventMillis"
|
||||
className="pipelineViewer__metric--eventMillis"
|
||||
warning={processorVertex.isSlow()}
|
||||
value={formatMetric(latestMillisPerEvent, '0.[00]a', 'ms/e')}
|
||||
/>
|
||||
),
|
||||
(
|
||||
<Metric
|
||||
key="eventsReceived"
|
||||
className="pipelineViewer__metric--events"
|
||||
value={formatMetric(latestEventsPerSecond, '0.[00]a', 'e/s received')}
|
||||
/>
|
||||
)
|
||||
<Metric
|
||||
key="cpuMetric"
|
||||
className="pipelineViewer__metric--cpuTime"
|
||||
warning={processorVertex.isTimeConsuming()}
|
||||
value={formatMetric(
|
||||
Math.round(percentOfTotalProcessorTime || 0),
|
||||
'0',
|
||||
'%',
|
||||
{ prependSpace: false }
|
||||
)}
|
||||
/>,
|
||||
<Metric
|
||||
key="eventMillis"
|
||||
className="pipelineViewer__metric--eventMillis"
|
||||
warning={processorVertex.isSlow()}
|
||||
value={formatMetric(latestMillisPerEvent, '0.[00]a', 'ms/e')}
|
||||
/>,
|
||||
<Metric
|
||||
key="eventsReceived"
|
||||
className="pipelineViewer__metric--events"
|
||||
value={formatMetric(latestEventsPerSecond, '0.[00]a', 'e/s received')}
|
||||
/>,
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -66,45 +65,36 @@ function renderPluginStatementMetrics(pluginType, vertex) {
|
|||
}
|
||||
|
||||
export function PluginStatement({
|
||||
statement: {
|
||||
hasExplicitId,
|
||||
id,
|
||||
name,
|
||||
pluginType,
|
||||
vertex
|
||||
},
|
||||
onShowVertexDetails
|
||||
statement: { hasExplicitId, id, name, pluginType, vertex },
|
||||
onShowVertexDetails,
|
||||
}) {
|
||||
const statementMetrics = renderPluginStatementMetrics(pluginType, vertex);
|
||||
const onNameButtonClick = () => { onShowVertexDetails(vertex); };
|
||||
const onNameButtonClick = () => {
|
||||
onShowVertexDetails(vertex);
|
||||
};
|
||||
|
||||
return (
|
||||
<EuiFlexGroup
|
||||
gutterSize="none"
|
||||
justifyContent="spaceBetween"
|
||||
alignItems="center"
|
||||
className="pipelineViewer__statement"
|
||||
gutterSize="none"
|
||||
justifyContent="spaceBetween"
|
||||
>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiFlexGroup
|
||||
gutterSize="xs"
|
||||
responsive={false}
|
||||
alignItems="center"
|
||||
>
|
||||
<EuiFlexGroup alignItems="center" gutterSize="xs" responsive={false}>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButtonEmpty
|
||||
size="xs"
|
||||
color="primary"
|
||||
iconType="dot"
|
||||
flush="left"
|
||||
className="pipelineViewer__plugin"
|
||||
color="primary"
|
||||
flush="left"
|
||||
iconType="dot"
|
||||
onClick={onNameButtonClick}
|
||||
size="xs"
|
||||
>
|
||||
<span>{name}</span>
|
||||
</EuiButtonEmpty>
|
||||
</EuiFlexItem>
|
||||
{
|
||||
hasExplicitId &&
|
||||
{hasExplicitId && (
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiBadge
|
||||
onClick={onNameButtonClick}
|
||||
|
@ -113,30 +103,29 @@ export function PluginStatement({
|
|||
{id}
|
||||
</EuiBadge>
|
||||
</EuiFlexItem>
|
||||
}
|
||||
)}
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
{
|
||||
statementMetrics &&
|
||||
{statementMetrics && (
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiFlexGroup
|
||||
gutterSize="s"
|
||||
>
|
||||
{statementMetrics}
|
||||
</EuiFlexGroup>
|
||||
<EuiFlexGroup gutterSize="s">{statementMetrics}</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
}
|
||||
)}
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
}
|
||||
|
||||
PluginStatement.propTypes = {
|
||||
onShowVertexDetails: PropTypes.func.isRequired,
|
||||
statement: PropTypes.shape({
|
||||
hasExplicitId: PropTypes.bool.isRequired,
|
||||
id: PropTypes.string.isRequired,
|
||||
name: PropTypes.string.isRequired,
|
||||
pluginType: PropTypes.string.isRequired,
|
||||
vertex: PropTypes.object.isRequired,
|
||||
vertex: PropTypes.shape({
|
||||
latestEventsPerSecond: PropTypes.number.isRequired,
|
||||
latestMillisPerEvent: PropTypes.number,
|
||||
percentOfTotalProcessorTime: PropTypes.number,
|
||||
}).isRequired,
|
||||
}).isRequired,
|
||||
onShowVertexDetails: PropTypes.func.isRequired,
|
||||
};
|
||||
|
|
|
@ -11,10 +11,7 @@ import { EuiSpacer, EuiText } from '@elastic/eui';
|
|||
export function Queue() {
|
||||
return (
|
||||
<div>
|
||||
<StatementListHeading
|
||||
iconType="logstashQueue"
|
||||
title="Queue"
|
||||
/>
|
||||
<StatementListHeading iconType="logstashQueue" title="Queue" />
|
||||
<EuiSpacer size="s" />
|
||||
<EuiText className="pipelineViewer__queueMessage">
|
||||
Queue metrics not available
|
||||
|
|
|
@ -6,10 +6,7 @@
|
|||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
EuiButtonEmpty,
|
||||
EuiCodeBlock,
|
||||
EuiFlexItem } from '@elastic/eui';
|
||||
import { EuiButtonEmpty, EuiCodeBlock, EuiFlexItem } from '@elastic/eui';
|
||||
import { PluginStatement as PluginStatementModel } from '../models/pipeline/plugin_statement';
|
||||
import { CollapsibleStatement } from './collapsible_statement';
|
||||
import { IfElement } from '../models/list/if_element';
|
||||
|
@ -17,10 +14,7 @@ import { PluginStatement } from './plugin_statement';
|
|||
|
||||
function renderStatementName(name, onVertexSelected) {
|
||||
return (
|
||||
<EuiFlexItem
|
||||
grow={false}
|
||||
key="statementName"
|
||||
>
|
||||
<EuiFlexItem grow={false} key="statementName">
|
||||
<EuiButtonEmpty
|
||||
color="text"
|
||||
size="xs"
|
||||
|
@ -36,30 +30,22 @@ function renderStatementName(name, onVertexSelected) {
|
|||
function renderIfStatement({ condition }, onVertexSelected) {
|
||||
return [
|
||||
renderStatementName('if', onVertexSelected),
|
||||
(
|
||||
<EuiFlexItem
|
||||
key="ifContent"
|
||||
grow={false}
|
||||
<EuiFlexItem key="ifContent" grow={false}>
|
||||
<EuiCodeBlock
|
||||
fontSize="s"
|
||||
paddingSize="none"
|
||||
transparentBackground={true}
|
||||
>
|
||||
<EuiCodeBlock
|
||||
fontSize="s"
|
||||
paddingSize="none"
|
||||
transparentBackground={true}
|
||||
>
|
||||
{condition}
|
||||
</EuiCodeBlock>
|
||||
</EuiFlexItem>
|
||||
)
|
||||
{condition}
|
||||
</EuiCodeBlock>
|
||||
</EuiFlexItem>,
|
||||
];
|
||||
}
|
||||
|
||||
function getStatementBody(
|
||||
isIf,
|
||||
statement,
|
||||
vertex,
|
||||
onShowVertexDetails
|
||||
) {
|
||||
const showVertexDetailsClicked = () => { onShowVertexDetails(vertex); };
|
||||
function getStatementBody(isIf, statement, vertex, onShowVertexDetails) {
|
||||
const showVertexDetailsClicked = () => {
|
||||
onShowVertexDetails(vertex);
|
||||
};
|
||||
|
||||
return isIf
|
||||
? renderIfStatement(statement, showVertexDetailsClicked)
|
||||
|
@ -69,7 +55,9 @@ function getStatementBody(
|
|||
function renderNestingSpacers(depth) {
|
||||
const spacers = [];
|
||||
for (let i = 0; i < depth; i += 1) {
|
||||
spacers.push(<div key={`spacer_${i}`} className="pipelineViewer__spacer" />);
|
||||
spacers.push(
|
||||
<div key={`spacer_${i}`} className="pipelineViewer__spacer" />
|
||||
);
|
||||
}
|
||||
return spacers;
|
||||
}
|
||||
|
@ -80,11 +68,11 @@ function renderStatement({
|
|||
element: {
|
||||
id,
|
||||
statement,
|
||||
statement: { vertex }
|
||||
statement: { vertex },
|
||||
},
|
||||
expand,
|
||||
isCollapsed,
|
||||
onShowVertexDetails
|
||||
onShowVertexDetails,
|
||||
}) {
|
||||
if (statement instanceof PluginStatementModel) {
|
||||
return (
|
||||
|
@ -132,9 +120,9 @@ Statement.propTypes = {
|
|||
element: PropTypes.shape({
|
||||
depth: PropTypes.number.isRequired,
|
||||
id: PropTypes.string.isRequired,
|
||||
statement: PropTypes.object.isRequired
|
||||
statement: PropTypes.object.isRequired,
|
||||
}).isRequired,
|
||||
expand: PropTypes.func.isRequired,
|
||||
isCollapsed: PropTypes.bool.isRequired,
|
||||
onShowVertexDetails: PropTypes.func.isRequired
|
||||
onShowVertexDetails: PropTypes.func.isRequired,
|
||||
};
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { Statement } from './statement';
|
||||
|
||||
function getCollapsedChildIds(elements, collapsedIds) {
|
||||
const collapsedChildIds = new Set();
|
||||
elements.forEach(({ id, parentId }) => {
|
||||
if (collapsedIds.has(parentId) || collapsedChildIds.has(parentId)) {
|
||||
collapsedChildIds.add(id);
|
||||
}
|
||||
});
|
||||
return collapsedChildIds;
|
||||
}
|
||||
|
||||
export class StatementList extends React.PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
collapsedIds: new Set(),
|
||||
collapsedChildIds: new Set(),
|
||||
};
|
||||
}
|
||||
|
||||
expand = elementId => {
|
||||
const collapsedIds = new Set(this.state.collapsedIds);
|
||||
collapsedIds.delete(elementId);
|
||||
this.updateCollapsedElement(collapsedIds);
|
||||
};
|
||||
|
||||
collapse = elementId => {
|
||||
const collapsedIds = new Set(this.state.collapsedIds);
|
||||
collapsedIds.add(elementId);
|
||||
this.updateCollapsedElement(collapsedIds);
|
||||
};
|
||||
|
||||
updateCollapsedElement = collapsedIds => {
|
||||
const { elements } = this.props;
|
||||
const collapsedChildIds = getCollapsedChildIds(elements, collapsedIds);
|
||||
|
||||
this.setState({
|
||||
collapsedIds,
|
||||
collapsedChildIds,
|
||||
});
|
||||
};
|
||||
|
||||
elementIsCollapsed = elementId => this.state.collapsedIds.has(elementId);
|
||||
|
||||
renderStatement = element => {
|
||||
const { id, parentId } = element;
|
||||
const { onShowVertexDetails } = this.props;
|
||||
|
||||
return this.state.collapsedIds.has(parentId) ||
|
||||
this.state.collapsedChildIds.has(parentId) ? null : (
|
||||
<Statement
|
||||
key={id}
|
||||
element={element}
|
||||
collapse={this.collapse}
|
||||
expand={this.expand}
|
||||
isCollapsed={this.elementIsCollapsed(id)}
|
||||
onShowVertexDetails={onShowVertexDetails}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
render() {
|
||||
const { elements } = this.props;
|
||||
|
||||
return (
|
||||
<ul className="pipelineViewer__list">
|
||||
{elements.map(this.renderStatement)}
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
StatementList.propTypes = {
|
||||
elements: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
id: PropTypes.string.isRequired,
|
||||
// top-level elements have null parentId
|
||||
parentId: PropTypes.string,
|
||||
})
|
||||
).isRequired,
|
||||
onShowVertexDetails: PropTypes.func.isRequired,
|
||||
};
|
|
@ -7,23 +7,22 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { StatementListHeading } from './statement_list_heading';
|
||||
import { Statement } from './statement';
|
||||
import { EuiSpacer } from '@elastic/eui';
|
||||
import { StatementList } from './statement_list';
|
||||
|
||||
export function StatementSection({
|
||||
iconType,
|
||||
headingText,
|
||||
elements,
|
||||
onShowVertexDetails
|
||||
onShowVertexDetails,
|
||||
}) {
|
||||
if (!elements.length) { return null; }
|
||||
if (!elements.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<StatementListHeading
|
||||
iconType={iconType}
|
||||
title={headingText}
|
||||
/>
|
||||
<StatementListHeading iconType={iconType} title={headingText} />
|
||||
<EuiSpacer size="s" />
|
||||
<StatementList
|
||||
elements={elements}
|
||||
|
@ -33,88 +32,15 @@ export function StatementSection({
|
|||
);
|
||||
}
|
||||
|
||||
function getCollapsedChildIds(elements, collapsedIds) {
|
||||
const collapsedChildIds = new Set();
|
||||
elements.forEach(({ id, parentId }) => {
|
||||
if (collapsedIds.has(parentId) || collapsedChildIds.has(parentId)) {
|
||||
collapsedChildIds.add(id);
|
||||
}
|
||||
});
|
||||
return collapsedChildIds;
|
||||
}
|
||||
|
||||
class StatementList extends React.PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
collapsedIds: new Set(),
|
||||
collapsedChildIds: new Set()
|
||||
};
|
||||
}
|
||||
|
||||
expand = elementId => {
|
||||
const collapsedIds = new Set(this.state.collapsedIds);
|
||||
collapsedIds.delete(elementId);
|
||||
this.updateCollapsedElement(collapsedIds);
|
||||
}
|
||||
|
||||
collapse = elementId => {
|
||||
const collapsedIds = new Set(this.state.collapsedIds);
|
||||
collapsedIds.add(elementId);
|
||||
this.updateCollapsedElement(collapsedIds);
|
||||
}
|
||||
|
||||
updateCollapsedElement = collapsedIds => {
|
||||
const { elements } = this.props;
|
||||
const collapsedChildIds = getCollapsedChildIds(elements, collapsedIds);
|
||||
|
||||
this.setState({
|
||||
collapsedIds,
|
||||
collapsedChildIds
|
||||
});
|
||||
}
|
||||
|
||||
elementIsCollapsed = elementId => this.state.collapsedIds.has(elementId);
|
||||
|
||||
renderStatement = element => {
|
||||
const { id, parentId } = element;
|
||||
const { onShowVertexDetails } = this.props;
|
||||
|
||||
return this.state.collapsedIds.has(parentId) || this.state.collapsedChildIds.has(parentId)
|
||||
? null
|
||||
: (
|
||||
<Statement
|
||||
key={id}
|
||||
element={element}
|
||||
collapse={this.collapse}
|
||||
expand={this.expand}
|
||||
isCollapsed={this.elementIsCollapsed(id)}
|
||||
onShowVertexDetails={onShowVertexDetails}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { elements } = this.props;
|
||||
|
||||
return (
|
||||
<ul className="pipelineViewer__list">
|
||||
{
|
||||
elements.map(this.renderStatement)
|
||||
}
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
StatementList.propTypes = {
|
||||
StatementSection.propTypes = {
|
||||
elements: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
id: PropTypes.string.isRequired,
|
||||
// top-level elements have null parentId
|
||||
parentId: PropTypes.string
|
||||
parentId: PropTypes.string,
|
||||
})
|
||||
).isRequired,
|
||||
headingText: PropTypes.string.isRequired,
|
||||
iconType: PropTypes.string.isRequired,
|
||||
onShowVertexDetails: PropTypes.func.isRequired,
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue