Skip to content

Commit

Permalink
added Time Range & Refresh Interval dropdowns in monitoring dashboard
Browse files Browse the repository at this point in the history
  • Loading branch information
abhi-kn committed Feb 26, 2020
1 parent 8e089e0 commit 8091fe3
Show file tree
Hide file tree
Showing 4 changed files with 185 additions and 5 deletions.
@@ -0,0 +1,24 @@
.odc-monitoring-dashboard-options {
display: flex;
float: right;
align-self: flex-end;
margin-right: 20px;
margin-top: -65px;
}

.odc-monitoring-dashboard-dropdown-title {
text-transform: capitalize;
}

.odc-monitoring-dashboard-dropdown-wrap {
display: flex;
flex-direction: column;
margin-right: 10px;
}

.odc-monitoring-dashboard-dropdown-button {
max-width: 280px !important; // allow truncation
min-width: 100px;
}


Expand Up @@ -2,8 +2,13 @@ import * as React from 'react';
import * as _ from 'lodash';
import { match as RMatch } from 'react-router-dom';
import { Helmet } from 'react-helmet';
import { Grid, GridItem } from '@patternfly/react-core';
import { Dropdown, DropdownToggle, DropdownItem, Grid, GridItem } from '@patternfly/react-core';

import { getURLSearchParams } from '@console/internal/components/utils';
import {
parsePrometheusDuration,
formatPrometheusDuration,
} from '@console/internal/components/utils/datetime';
import ConnectedMonitoringDashboardGraph from './MonitoringDashboardGraph';
import {
monitoringDashboardQueries,
Expand All @@ -12,12 +17,136 @@ import {
topWorkloadMetricsQueries,
} from '../queries';
import MonitoringDasboardPodCount from './MonitoringDashboardPodCount';
import { RedExclamationCircleIcon } from '@console/shared';
import './MonitoringDashboard.scss';

type VariableDropdownProps = {
isError?: boolean;
items: { [key: string]: string };
label: string;
onChange: (v: string) => void;
selectedKey: string;
};

type TimespanDropdownProps = {
timespan: number;
onTimespanChange: (v: string) => void;
};

type PollIntervalDropdownProps = {
pollInterval: number;
onPollIntervalChange: (v: string) => void;
};

interface MonitoringDashboardProps {
type MonitoringDashboardProps = {
match: RMatch<{
ns?: string;
}>;
}
};

const useBoolean = (initialValue: boolean): [boolean, () => void, () => void, () => void] => {
const [value, setValue] = React.useState(initialValue);
const toggle = React.useCallback(() => setValue((v) => !v), []);
const setTrue = React.useCallback(() => setValue(true), []);
const setFalse = React.useCallback(() => setValue(false), []);
return [value, toggle, setTrue, setFalse];
};

const VariableDropdown: React.FC<VariableDropdownProps> = ({
isError = false,
items,
label,
onChange,
selectedKey,
}) => {
const [isOpen, toggleIsOpen, , setClosed] = useBoolean(false);

return (
<div className="form-group odc-monitoring-dashboard-dropdown-wrap">
<label className="odc-monitoring-dashboard-dropdown-title">{label}</label>
{isError ? (
<Dropdown
toggle={
<DropdownToggle className="odc-monitoring-dashboard-dropdown-button" isDisabled>
<RedExclamationCircleIcon /> Error loading options
</DropdownToggle>
}
/>
) : (
<Dropdown
dropdownItems={_.map(items, (name, key) => (
<DropdownItem component="button" key={key} onClick={() => onChange(key)}>
{name}
</DropdownItem>
))}
isOpen={isOpen}
onSelect={setClosed}
toggle={
<DropdownToggle
className="odc-monitoring-dashboard-dropdown-button"
onToggle={toggleIsOpen}
>
{items[selectedKey]}
</DropdownToggle>
}
/>
)}
</div>
);
};

const timespanOptions = {
'5m': '5 minutes',
'15m': '15 minutes',
'30m': '30 minutes',
'1h': '1 hour',
'2h': '2 hours',
'6h': '6 hours',
'12h': '12 hours',
'1d': '1 day',
'2d': '2 days',
'1w': '1 week',
'2w': '2 weeks',
};

const TimespanDropdown: React.FC<TimespanDropdownProps> = ({ timespan, onTimespanChange }) => {
return (
<VariableDropdown
items={timespanOptions}
label="Time Range"
onChange={onTimespanChange}
selectedKey={formatPrometheusDuration(timespan)}
/>
);
};

const pollOffText = 'Off';
const pollIntervalOptions = {
[pollOffText]: pollOffText,
'15s': '15 seconds',
'30s': '30 seconds',
'1m': '1 minute',
'5m': '5 minutes',
'15m': '15 minutes',
'30m': '30 minutes',
'1h': '1 hour',
'2h': '2 hours',
'1d': '1 day',
};

const PollIntervalDropdown: React.FC<PollIntervalDropdownProps> = ({
pollInterval,
onPollIntervalChange,
}) => {
return (
<VariableDropdown
items={pollIntervalOptions}
label="Refresh Interval"
onChange={onPollIntervalChange}
selectedKey={pollInterval === 0 ? pollOffText : formatPrometheusDuration(pollInterval)}
/>
);
};

const MonitoringDashboard: React.FC<MonitoringDashboardProps> = ({ match }) => {
const namespace = match.params.ns;
Expand All @@ -27,12 +156,29 @@ const MonitoringDashboard: React.FC<MonitoringDashboardProps> = ({ match }) => {
workloadName && workloadType
? [...topWorkloadMetricsQueries, ...workloadMetricsQueries]
: monitoringDashboardQueries;
const [timespan, setTimespan] = React.useState(parsePrometheusDuration('30m'));
const onTimespanChange = React.useCallback(
(v: string) => setTimespan(parsePrometheusDuration(v)),
[setTimespan],
);
const [pollInterval, setPollInterval] = React.useState(parsePrometheusDuration('30s'));
const onPollIntervalChange = React.useCallback(
(v: string) => setPollInterval(parsePrometheusDuration(v)),
[setPollInterval],
);

return (
<>
<Helmet>
<title>Dashboard</title>
</Helmet>
<div className="odc-monitoring-dashboard-options">
<TimespanDropdown timespan={timespan} onTimespanChange={onTimespanChange} />
<PollIntervalDropdown
pollInterval={pollInterval}
onPollIntervalChange={onPollIntervalChange}
/>
</div>
<Grid className="co-m-pane__body" gutter="md">
<GridItem span={3} rowSpan={1}>
<MonitoringDasboardPodCount namespace={namespace} />
Expand All @@ -46,6 +192,8 @@ const MonitoringDashboard: React.FC<MonitoringDashboardProps> = ({ match }) => {
query={q.query({ namespace, workloadName, workloadType })}
humanize={q.humanize}
byteDataType={q.byteDataType}
timespan={timespan}
pollInterval={pollInterval}
/>
</GridItem>
))}
Expand Down
Expand Up @@ -23,18 +23,22 @@ type OwnProps = {
graphType?: GraphTypes;
humanize: Humanize;
byteDataType: ByteDataTypes;
timespan?: number;
pollInterval?: number;
};

type MonitoringDashboardGraphProps = OwnProps & DispatchProps;

const defaultTimespan = 30 * 60 * 1000;
const DEFAULT_TIME_SPAN = 30 * 60 * 1000;

export const MonitoringDashboardGraph: React.FC<MonitoringDashboardGraphProps> = ({
query,
namespace,
title,
patchQuery,
graphType = GraphTypes.area,
timespan,
pollInterval,
}) => {
return (
<div className="odc-monitoring-dashboard-graph">
Expand All @@ -43,10 +47,12 @@ export const MonitoringDashboardGraph: React.FC<MonitoringDashboardGraphProps> =
<div onMouseEnter={() => patchQuery({ query })}>
<QueryBrowser
hideControls
defaultTimespan={defaultTimespan}
defaultTimespan={DEFAULT_TIME_SPAN}
namespace={namespace}
queries={[query]}
isStack={graphType === GraphTypes.area}
timespan={timespan}
pollInterval={pollInterval}
/>
</div>
</PrometheusGraphLink>
Expand Down
Expand Up @@ -18,6 +18,8 @@ describe('Monitoring Dashboard graph', () => {
humanize: query.humanize,
byteDataType: query.byteDataType,
patchQuery: jest.fn(),
timespan: 1800000,
pollInterval: 30000,
};
});

Expand Down

0 comments on commit 8091fe3

Please sign in to comment.