Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[InfraOps] Preserve time values when navigating from the waffle map to the logs and details pages #24666

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import React from 'react';
import styled from 'styled-components';
import { InfraNodeType } from '../../../common/graphql/types';
import { InfraNodeType, InfraTimerangeInput } from '../../../common/graphql/types';
import {
InfraWaffleMapBounds,
InfraWaffleMapGroupOfGroups,
Expand All @@ -22,6 +22,7 @@ interface Props {
formatter: (val: number) => string;
bounds: InfraWaffleMapBounds;
nodeType: InfraNodeType;
timeRange: InfraTimerangeInput;
}

export const GroupOfGroups: React.SFC<Props> = props => {
Expand All @@ -39,6 +40,7 @@ export const GroupOfGroups: React.SFC<Props> = props => {
formatter={props.formatter}
bounds={props.bounds}
nodeType={props.nodeType}
timeRange={props.timeRange}
/>
))}
</Groups>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import React from 'react';
import styled from 'styled-components';
import { InfraNodeType } from '../../../common/graphql/types';
import { InfraNodeType, InfraTimerangeInput } from '../../../common/graphql/types';
import {
InfraWaffleMapBounds,
InfraWaffleMapGroupOfNodes,
Expand All @@ -23,6 +23,7 @@ interface Props {
isChild: boolean;
bounds: InfraWaffleMapBounds;
nodeType: InfraNodeType;
timeRange: InfraTimerangeInput;
}

export const GroupOfNodes: React.SFC<Props> = ({
Expand All @@ -33,6 +34,7 @@ export const GroupOfNodes: React.SFC<Props> = ({
isChild = false,
bounds,
nodeType,
timeRange,
}) => {
const width = group.width > 200 ? group.width : 200;
return (
Expand All @@ -48,6 +50,7 @@ export const GroupOfNodes: React.SFC<Props> = ({
formatter={formatter}
bounds={bounds}
nodeType={nodeType}
timeRange={timeRange}
/>
))}
</Nodes>
Expand Down
13 changes: 9 additions & 4 deletions x-pack/plugins/infra/public/components/waffle/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { EuiButton, EuiEmptyPrompt } from '@elastic/eui';
import { get, max, min } from 'lodash';
import React from 'react';
import styled from 'styled-components';
import { InfraMetricType, InfraNodeType } from '../../../common/graphql/types';
import { InfraMetricType, InfraNodeType, InfraTimerangeInput } from '../../../common/graphql/types';
import {
isWaffleMapGroupWithGroups,
isWaffleMapGroupWithNodes,
Expand Down Expand Up @@ -35,6 +35,7 @@ interface Props {
loading: boolean;
reload: () => void;
onDrilldown: (filter: KueryFilterQuery) => void;
timeRange: InfraTimerangeInput;
}

interface MetricFormatter {
Expand Down Expand Up @@ -90,7 +91,7 @@ const calculateBoundsFromMap = (map: InfraWaffleData): InfraWaffleMapBounds => {

export class Waffle extends React.Component<Props, {}> {
public render() {
const { loading, map, reload } = this.props;
const { loading, map, reload, timeRange } = this.props;
if (loading) {
return <InfraLoadingPanel height="100%" width="100%" text="Loading data" />;
} else if (!loading && map && map.length === 0) {
Expand Down Expand Up @@ -132,7 +133,7 @@ export class Waffle extends React.Component<Props, {}> {
data-test-subj="waffleMap"
>
<WaffleMapInnerContainer>
{groupsWithLayout.map(this.renderGroup(bounds))}
{groupsWithLayout.map(this.renderGroup(bounds, timeRange))}
</WaffleMapInnerContainer>
<Legend
formatter={this.formatter}
Expand Down Expand Up @@ -169,7 +170,9 @@ export class Waffle extends React.Component<Props, {}> {
return;
};

private renderGroup = (bounds: InfraWaffleMapBounds) => (group: InfraWaffleMapGroup) => {
private renderGroup = (bounds: InfraWaffleMapBounds, timeRange: InfraTimerangeInput) => (
group: InfraWaffleMapGroup
) => {
if (isWaffleMapGroupWithGroups(group)) {
return (
<GroupOfGroups
Expand All @@ -180,6 +183,7 @@ export class Waffle extends React.Component<Props, {}> {
formatter={this.formatter}
bounds={bounds}
nodeType={this.props.nodeType}
timeRange={timeRange}
/>
);
}
Expand All @@ -194,6 +198,7 @@ export class Waffle extends React.Component<Props, {}> {
isChild={false}
bounds={bounds}
nodeType={this.props.nodeType}
timeRange={timeRange}
/>
);
}
Expand Down
5 changes: 4 additions & 1 deletion x-pack/plugins/infra/public/components/waffle/node.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { EuiToolTip } from '@elastic/eui';
import { darken, readableColor } from 'polished';
import React from 'react';
import styled from 'styled-components';
import { InfraTimerangeInput } from 'x-pack/plugins/infra/common/graphql/types';
import { InfraNodeType } from '../../../server/lib/adapters/nodes';
import { InfraWaffleMapBounds, InfraWaffleMapNode, InfraWaffleMapOptions } from '../../lib/lib';
import { colorFromValue } from './lib/color_from_value';
Expand All @@ -26,12 +27,13 @@ interface Props {
formatter: (val: number) => string;
bounds: InfraWaffleMapBounds;
nodeType: InfraNodeType;
timeRange: InfraTimerangeInput;
}

export class Node extends React.PureComponent<Props, State> {
public readonly state: State = initialState;
public render() {
const { nodeType, node, options, squareSize, bounds, formatter } = this.props;
const { nodeType, node, options, squareSize, bounds, formatter, timeRange } = this.props;
const { isPopoverOpen } = this.state;
const { metric } = node;
const valueMode = squareSize > 110;
Expand All @@ -45,6 +47,7 @@ export class Node extends React.PureComponent<Props, State> {
isPopoverOpen={isPopoverOpen}
closePopover={this.closePopover}
options={options}
timeRange={timeRange}
>
<EuiToolTip position="top" content={`${node.name} | ${value}`}>
<NodeContainer
Expand Down
77 changes: 22 additions & 55 deletions x-pack/plugins/infra/public/components/waffle/node_context_menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,14 @@

import { EuiContextMenu, EuiContextMenuPanelDescriptor, EuiPopover } from '@elastic/eui';
import React from 'react';
import { InfraNodeType } from '../../../common/graphql/types';

import { InfraNodeType, InfraTimerangeInput } from '../../../common/graphql/types';
import { InfraWaffleMapNode, InfraWaffleMapOptions } from '../../lib/lib';
import {
getContainerDetailUrl,
getContainerLogsUrl,
getHostDetailUrl,
getHostLogsUrl,
getPodDetailUrl,
getPodLogsUrl,
} from '../../pages/link_to';
import { getNodeDetailUrl, getNodeLogsUrl } from '../../pages/link_to';

interface Props {
options: InfraWaffleMapOptions;
timeRange: InfraTimerangeInput;
node: InfraWaffleMapNode;
nodeType: InfraNodeType;
isPopoverOpen: boolean;
Expand All @@ -27,14 +22,30 @@ interface Props {

export const NodeContextMenu: React.SFC<Props> = ({
options,
timeRange,
children,
node,
isPopoverOpen,
closePopover,
nodeType,
}) => {
const nodeLogsUrl = getNodeLogsUrl(nodeType, node);
const nodeDetailUrl = getNodeDetailUrl(nodeType, node);
const nodeName = node.path.length > 0 ? node.path[node.path.length - 1].value : undefined;
const nodeLogsUrl = nodeName
? getNodeLogsUrl({
nodeType,
nodeName,
time: timeRange.to,
})
: undefined;
const nodeDetailUrl = nodeName
? getNodeDetailUrl({
nodeType,
nodeName,
from: timeRange.from,
to: timeRange.to,
})
: undefined;

const panels: EuiContextMenuPanelDescriptor[] = [
{
id: 0,
Expand Down Expand Up @@ -72,47 +83,3 @@ export const NodeContextMenu: React.SFC<Props> = ({
</EuiPopover>
);
};

const getNodeLogsUrl = (
nodeType: 'host' | 'container' | 'pod',
{ path }: InfraWaffleMapNode
): string | undefined => {
if (path.length <= 0) {
return undefined;
}

const lastPathSegment = path[path.length - 1];

switch (nodeType) {
case 'host':
return getHostLogsUrl({ hostname: lastPathSegment.value });
case 'container':
return getContainerLogsUrl({ containerId: lastPathSegment.value });
case 'pod':
return getPodLogsUrl({ podId: lastPathSegment.value });
default:
return undefined;
}
};

const getNodeDetailUrl = (
nodeType: 'host' | 'container' | 'pod',
{ path }: InfraWaffleMapNode
): string | undefined => {
if (path.length <= 0) {
return undefined;
}

const lastPathSegment = path[path.length - 1];

switch (nodeType) {
case 'host':
return getHostDetailUrl({ name: lastPathSegment.value });
case 'container':
return getContainerDetailUrl({ name: lastPathSegment.value });
case 'pod':
return getPodDetailUrl({ name: lastPathSegment.value });
default:
return undefined;
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { createSelector } from 'reselect';
import { metricTimeActions, metricTimeSelectors, State } from '../../store';
import { asChildFunctionRenderer } from '../../utils/typed_react';
import { bindPlainActionCreators } from '../../utils/typed_redux';
import { UrlStateContainer } from '../../utils/url_state';
import { replaceStateKeyInQueryString, UrlStateContainer } from '../../utils/url_state';

export const withMetricsTime = connect(
(state: State) => ({
Expand Down Expand Up @@ -94,3 +94,15 @@ const mapToTimeUrlState = (value: any) =>
value && (typeof value.to === 'number' && typeof value.from === 'number') ? value : undefined;

const mapToAutoReloadUrlState = (value: any) => (typeof value === 'boolean' ? value : undefined);

export const replaceMetricTimeInQueryString = (from: number, to: number) =>
Number.isNaN(from) || Number.isNaN(to)
? (value: string) => value
: replaceStateKeyInQueryString<MetricTimeUrlState>('metricTime', {
autoReload: false,
time: {
interval: '>=1m',
from,
to,
},
});
1 change: 1 addition & 0 deletions x-pack/plugins/infra/public/pages/home/page_content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export const HomePageContent: React.SFC = () => (
options={{ ...wafflemap, metric, fields: configuredFields, groupBy }}
reload={refetch}
onDrilldown={applyFilterQuery}
timeRange={currentTimeRange}
/>
)}
</WithWaffleNodes>
Expand Down

This file was deleted.

8 changes: 2 additions & 6 deletions x-pack/plugins/infra/public/pages/link_to/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,5 @@
*/

export { LinkToPage } from './link_to';
export { getContainerLogsUrl, RedirectToContainerLogs } from './redirect_to_container_logs';
export { getHostLogsUrl, RedirectToHostLogs } from './redirect_to_host_logs';
export { getPodLogsUrl, RedirectToPodLogs } from './redirect_to_pod_logs';
export { getHostDetailUrl, RedirectToHostDetail } from './redirect_to_host_detail';
export { getContainerDetailUrl, RedirectToContainerDetail } from './redirect_to_container_detail';
export { getPodDetailUrl, RedirectToPodDetail } from './redirect_to_pod_detail';
export { getNodeLogsUrl, RedirectToNodeLogs } from './redirect_to_node_logs';
export { getNodeDetailUrl, RedirectToNodeDetail } from './redirect_to_node_detail';
21 changes: 8 additions & 13 deletions x-pack/plugins/infra/public/pages/link_to/link_to.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,8 @@
import React from 'react';
import { match as RouteMatch, Redirect, Route, Switch } from 'react-router-dom';

import { RedirectToContainerDetail } from './redirect_to_container_detail';
import { RedirectToContainerLogs } from './redirect_to_container_logs';
import { RedirectToHostDetail } from './redirect_to_host_detail';
import { RedirectToHostLogs } from './redirect_to_host_logs';
import { RedirectToPodDetail } from './redirect_to_pod_detail';
import { RedirectToPodLogs } from './redirect_to_pod_logs';
import { RedirectToNodeDetail } from './redirect_to_node_detail';
import { RedirectToNodeLogs } from './redirect_to_node_logs';

interface LinkToPageProps {
match: RouteMatch<{}>;
Expand All @@ -25,14 +21,13 @@ export class LinkToPage extends React.Component<LinkToPageProps> {
return (
<Switch>
<Route
path={`${match.url}/container-logs/:containerId`}
component={RedirectToContainerLogs}
path={`${match.url}/:nodeType(host|container|pod)-logs/:nodeName`}
component={RedirectToNodeLogs}
/>
<Route
path={`${match.url}/:nodeType(host|container|pod)-detail/:nodeName`}
component={RedirectToNodeDetail}
/>
<Route path={`${match.url}/host-logs/:hostname`} component={RedirectToHostLogs} />
<Route path={`${match.url}/pod-logs/:podId`} component={RedirectToPodLogs} />
<Route path={`${match.url}/host-detail/:name`} component={RedirectToHostDetail} />
<Route path={`${match.url}/pod-detail/:name`} component={RedirectToPodDetail} />
<Route path={`${match.url}/container-detail/:name`} component={RedirectToContainerDetail} />
<Redirect to="/home" />
</Switch>
);
Expand Down

This file was deleted.

Loading