Skip to content

Commit

Permalink
[Metrics UI] Add basic interaction and shell for node details overlay (
Browse files Browse the repository at this point in the history
…#82013)

* Add basic interaction and shell for node details overlay

* Fix typecheck

* Remove context menu tests because context menu doesn't exist

* Remove outdated tests

* Remove unused variable

* Show the old overlay by default

* Fix typecheck

* Fix typo

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
# Conflicts:
#	x-pack/test/functional/apps/infra/feature_controls/infrastructure_security.ts
  • Loading branch information
phillipb committed Nov 15, 2020
1 parent 2a0f465 commit 67aacf4
Show file tree
Hide file tree
Showing 9 changed files with 237 additions and 97 deletions.
Original file line number Diff line number Diff line change
@@ -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 { EuiTabbedContent } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { EuiPanel } from '@elastic/eui';
import React, { CSSProperties, useMemo } from 'react';
import { EuiText } from '@elastic/eui';
import { EuiFlexGroup, EuiFlexItem, EuiButtonEmpty } from '@elastic/eui';
import { euiStyled } from '../../../../../../../observability/public';
import { InfraWaffleMapNode, InfraWaffleMapOptions } from '../../../../../lib/lib';
import { InventoryItemType } from '../../../../../../common/inventory_models/types';
import { MetricsTab } from './tabs/metrics';
import { LogsTab } from './tabs/logs';
import { ProcessesTab } from './tabs/processes';
import { PropertiesTab } from './tabs/properties';

interface Props {
isOpen: boolean;
onClose(): void;
options: InfraWaffleMapOptions;
currentTime: number;
node: InfraWaffleMapNode;
nodeType: InventoryItemType;
}
export const NodeContextPopover = ({
isOpen,
node,
nodeType,
currentTime,
options,
onClose,
}: Props) => {
const tabConfigs = [MetricsTab, LogsTab, ProcessesTab, PropertiesTab];

const tabs = useMemo(() => {
return tabConfigs.map((m) => {
const TabContent = m.content;
return {
...m,
content: (
<TabContent node={node} nodeType={nodeType} currentTime={currentTime} options={options} />
),
};
});
}, [tabConfigs, node, nodeType, currentTime, options]);

if (!isOpen) {
return null;
}

return (
<EuiPanel hasShadow={true} paddingSize={'none'} style={panelStyle}>
<OverlayHeader>
<EuiFlexGroup alignItems={'center'}>
<EuiFlexItem grow={true}>
<EuiText>
<h4>{node.name}</h4>
</EuiText>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButtonEmpty onClick={onClose} iconType={'cross'}>
<FormattedMessage id="xpack.infra.infra.nodeDetails.close" defaultMessage="Close" />
</EuiButtonEmpty>
</EuiFlexItem>
</EuiFlexGroup>
</OverlayHeader>
<EuiTabbedContent tabs={tabs} />
</EuiPanel>
);
};

const OverlayHeader = euiStyled.div`
border-color: ${(props) => props.theme.eui.euiBorderColor};
border-bottom-width: ${(props) => props.theme.eui.euiBorderWidthThick};
padding: ${(props) => props.theme.eui.euiSizeS};
padding-bottom: 0;
overflow: hidden;
`;

const panelStyle: CSSProperties = {
position: 'absolute',
right: 10,
top: -100,
width: '50%',
maxWidth: 600,
zIndex: 2,
height: '50vh',
overflow: 'hidden',
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import React from 'react';
import { i18n } from '@kbn/i18n';
import { TabContent, TabProps } from './shared';

const TabComponent = (props: TabProps) => {
return <TabContent>Logs Placeholder</TabContent>;
};

export const LogsTab = {
id: 'logs',
name: i18n.translate('xpack.infra.nodeDetails.tabs.logs', {
defaultMessage: 'Logs',
}),
content: TabComponent,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import React from 'react';
import { i18n } from '@kbn/i18n';
import { TabContent, TabProps } from './shared';

const TabComponent = (props: TabProps) => {
return <TabContent>Metrics Placeholder</TabContent>;
};

export const MetricsTab = {
id: 'metrics',
name: i18n.translate('xpack.infra.nodeDetails.tabs.metrics', {
defaultMessage: 'Metrics',
}),
content: TabComponent,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import React from 'react';
import { i18n } from '@kbn/i18n';
import { TabContent, TabProps } from './shared';

const TabComponent = (props: TabProps) => {
return <TabContent>Processes Placeholder</TabContent>;
};

export const ProcessesTab = {
id: 'processes',
name: i18n.translate('xpack.infra.nodeDetails.tabs.processes', {
defaultMessage: 'Processes',
}),
content: TabComponent,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import React from 'react';
import { i18n } from '@kbn/i18n';
import { TabContent, TabProps } from './shared';

const TabComponent = (props: TabProps) => {
return <TabContent>Properties Placeholder</TabContent>;
};

export const PropertiesTab = {
id: 'properties',
name: i18n.translate('xpack.infra.nodeDetails.tabs.properties', {
defaultMessage: 'Properties',
}),
content: TabComponent,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* 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 { InventoryItemType } from '../../../../../../../common/inventory_models/types';
import { InfraWaffleMapOptions, InfraWaffleMapNode } from '../../../../../../lib/lib';
import { euiStyled } from '../../../../../../../../observability/public';

export interface TabProps {
options: InfraWaffleMapOptions;
currentTime: number;
node: InfraWaffleMapNode;
nodeType: InventoryItemType;
}

export const TabContent = euiStyled.div`
padding: ${(props) => props.theme.eui.paddingSizes.l};
`;
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,21 @@ import React from 'react';
import { i18n } from '@kbn/i18n';

import { first } from 'lodash';
import { ConditionalToolTip } from './conditional_tooltip';
import { euiStyled } from '../../../../../../../observability/public';
import {
InfraWaffleMapBounds,
InfraWaffleMapNode,
InfraWaffleMapOptions,
} from '../../../../../lib/lib';
import { colorFromValue } from '../../lib/color_from_value';
import { NodeContextMenu } from './node_context_menu';
import { InventoryItemType } from '../../../../../../common/inventory_models/types';
import { NodeContextPopover } from '../node_details/overlay';

import { NodeContextMenu } from './node_context_menu';

const initialState = {
isPopoverOpen: false,
isOverlayOpen: false,
};

type State = Readonly<typeof initialState>;
Expand Down Expand Up @@ -53,22 +55,16 @@ export const Node = class extends React.PureComponent<Props, State> {
values: { nodeName: node.name },
});
return (
<NodeContextMenu
node={node}
nodeType={nodeType}
isPopoverOpen={isPopoverOpen}
closePopover={this.closePopover}
options={options}
currentTime={currentTime}
popoverPosition="downCenter"
>
<ConditionalToolTip
currentTime={currentTime}
formatter={formatter}
hidden={isPopoverOpen}
<>
<NodeContextMenu
node={node}
options={options}
nodeType={nodeType}
isPopoverOpen={isPopoverOpen}
closePopover={this.closePopover}
options={options}
currentTime={currentTime}
popoverPosition="downCenter"
openNewOverlay={this.toggleNewOverlay}
>
<NodeContainer
data-test-subj="nodeContainer"
Expand All @@ -92,15 +88,30 @@ export const Node = class extends React.PureComponent<Props, State> {
</SquareInner>
</SquareOuter>
</NodeContainer>
</ConditionalToolTip>
</NodeContextMenu>
</NodeContextMenu>
<NodeContextPopover
node={node}
nodeType={nodeType}
isOpen={this.state.isOverlayOpen}
options={options}
currentTime={currentTime}
onClose={this.toggleNewOverlay}
/>
</>
);
}

private togglePopover = () => {
this.setState((prevState) => ({ isPopoverOpen: !prevState.isPopoverOpen }));
};

private toggleNewOverlay = () => {
this.setState((prevState) => ({
isPopoverOpen: !prevState.isOverlayOpen === true ? false : prevState.isPopoverOpen,
isOverlayOpen: !prevState.isOverlayOpen,
}));
};

private closePopover = () => {
if (this.state.isPopoverOpen) {
this.setState({ isPopoverOpen: false });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ interface Props {
isPopoverOpen: boolean;
closePopover: () => void;
popoverPosition: EuiPopoverProps['anchorPosition'];
openNewOverlay?: () => void;
}

export const NodeContextMenu: React.FC<Props & { theme?: EuiTheme }> = withTheme(
Expand All @@ -50,6 +51,7 @@ export const NodeContextMenu: React.FC<Props & { theme?: EuiTheme }> = withTheme
nodeType,
popoverPosition,
theme,
openNewOverlay,
}) => {
const [flyoutVisible, setFlyoutVisible] = useState(false);
const inventoryModel = findInventoryModel(nodeType);
Expand Down Expand Up @@ -159,6 +161,14 @@ export const NodeContextMenu: React.FC<Props & { theme?: EuiTheme }> = withTheme
},
};

const openNewOverlayMenuItem: SectionLinkProps = {
label: i18n.translate('xpack.infra.nodeContextMenu.openNewOverlay', {
defaultMessage: '**** [NEW] Overlay ***',
}),
style: { color: theme?.eui.euiLinkColor || '#006BB4', fontWeight: 500, padding: 0 },
onClick: openNewOverlay,
};

return (
<>
<ActionMenu
Expand Down Expand Up @@ -194,6 +204,7 @@ export const NodeContextMenu: React.FC<Props & { theme?: EuiTheme }> = withTheme
<SectionLink data-test-subj="viewApmTracesContextMenuItem" {...apmTracesMenuItem} />
<SectionLink {...uptimeMenuItem} />
<SectionLink {...createAlertMenuItem} />
<SectionLink {...openNewOverlayMenuItem} />
</SectionLinks>
</Section>
</div>
Expand Down
Loading

0 comments on commit 67aacf4

Please sign in to comment.