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

Monitoring Dashboards: Add currently displayed dashboard to URL #4005

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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion frontend/public/components/monitoring.tsx
Expand Up @@ -1557,7 +1557,7 @@ const PollerPages = () => {
export const MonitoringUI = () => (
<Switch>
<Redirect from="/monitoring" exact to="/monitoring/alerts" />
<Route path="/monitoring/dashboards" exact component={MonitoringDashboardsPage} />
<Route path="/monitoring/dashboards/:board?" exact component={MonitoringDashboardsPage} />
<Route path="/monitoring/query-browser" exact component={QueryBrowserPage} />
<Route path="/monitoring/silences/~new" exact component={CreateSilence} />
<Route component={PollerPages} />
Expand Down
19 changes: 8 additions & 11 deletions frontend/public/components/monitoring/_monitoring.scss
@@ -1,7 +1,3 @@
.co-m-pane__heading--monitoring-dashboards {
justify-content: flex-start;
}

.monitoring-dashboards__card-header {
flex: 20 0 auto;
}
Expand All @@ -11,17 +7,14 @@
}

.monitoring-dashboards__dropdown-wrap {
margin-bottom: 10px;
margin-left: 20px;
margin-right: 20px;
}

.monitoring-dashboards__options {
display: flex;
justify-content: space-between;
}

.monitoring-dashboards__options-group {
display: flex;
float: right;
margin-right: -20px;
margin-top: -20px;
}

.monitoring-dashboards__panel {
Expand Down Expand Up @@ -52,6 +45,10 @@
overflow-x: auto;
}

.monitoring-dashboards__variables {
display: flex;
}

.query-browser__toggle-graph {
margin-bottom: 5px;
float: right;
Expand Down
88 changes: 47 additions & 41 deletions frontend/public/components/monitoring/dashboards/index.tsx
Expand Up @@ -15,7 +15,7 @@ import { k8sBasePath } from '../../../module/k8s';
import { ErrorBoundaryFallback } from '../../error';
import { RootState } from '../../../redux';
import { getPrometheusURL, PrometheusEndpoint } from '../../graphs/helpers';
import { Dropdown, LoadingInline, useSafeFetch } from '../../utils';
import { Dropdown, history, LoadingInline, useSafeFetch } from '../../utils';
import { parsePrometheusDuration } from '../../utils/datetime';
import { withFallback } from '../../utils/error-boundary';
import BarChart from './bar-chart';
Expand All @@ -40,8 +40,8 @@ const VariableDropdown: React.FC<VariableDropdownProps> = ({
selected,
title,
}) => (
<div className="monitoring-dashboards__dropdown-wrap">
{title && <h4>{title}</h4>}
<div className="form-group monitoring-dashboards__dropdown-wrap">
{title && <label>{title}</label>}
<Dropdown
buttonClassName={buttonClassName}
items={_.zipObject(options, options)}
Expand Down Expand Up @@ -181,17 +181,17 @@ const Board: React.FC<BoardProps> = ({ board, patchVariable, pollInterval, times
);

React.useEffect(() => {
setData(undefined);
setError(undefined);
const path = `${k8sBasePath}/api/v1/namespaces/openshift-monitoring/configmaps/grafana-dashboard-${board}`;
safeFetch(path)
.then((response) => {
const json = _.get(response, ['data', `${board}.json`]);
if (!json) {
setData(undefined);
setError('Dashboard definition JSON not found');
} else {
const newData = JSON.parse(json);
setData(newData);
setError(undefined);

const newVars = _.get(newData, 'templating.list') as TemplateVariable[];
const optionsVars = _.filter(newVars, (v) => v.type === 'query' || v.type === 'interval');
Expand All @@ -212,12 +212,14 @@ const Board: React.FC<BoardProps> = ({ board, patchVariable, pollInterval, times
})
.catch((err) => {
if (err.name !== 'AbortError') {
setData(undefined);
setError(_.get(err, 'json.error', err.message));
}
});
}, [board, loadVariableValues, patchVariable, safeFetch]);

if (!board) {
return null;
}
if (error) {
return <ErrorAlert message={error} />;
}
Expand All @@ -243,16 +245,20 @@ const Board: React.FC<BoardProps> = ({ board, patchVariable, pollInterval, times
const MonitoringDashboardsPage_: React.FC<MonitoringDashboardsPageProps> = ({
clearVariables,
patchVariable,
match,
}) => {
const { board } = match.params;

const [pollInterval, setPollInterval] = React.useState(
parsePrometheusDuration(defaultPollInterval),
);
const [timespan, setTimespan] = React.useState(parsePrometheusDuration(defaultTimespan));
const [board, setBoard] = React.useState(boards[0]);

const onBoardChange = (newBoard: string) => {
clearVariables();
setBoard(newBoard);
if (newBoard !== board) {
clearVariables();
history.replace(`/monitoring/dashboards/${newBoard}`);
}
};

return (
Expand All @@ -261,42 +267,41 @@ const MonitoringDashboardsPage_: React.FC<MonitoringDashboardsPageProps> = ({
<title>Metrics Dashboards</title>
</Helmet>
<div className="co-m-nav-title co-m-nav-title--detail">
<h1 className="co-m-pane__heading co-m-pane__heading--monitoring-dashboards">
Metrics Dashboards
<VariableDropdown onChange={onBoardChange} options={boards} selected={boards[0]} />
</h1>
<div className="monitoring-dashboards__options">
<div className="monitoring-dashboards__options-group">
<AllVariableDropdowns />
</div>
<div className="monitoring-dashboards__options-group">
<VariableDropdown
buttonClassName="monitoring-dashboards__dropdown"
onChange={(v: string) => setTimespan(parsePrometheusDuration(v))}
options={timespanOptions}
selected={defaultTimespan}
title="Time Range"
/>
<VariableDropdown
onChange={(v: string) =>
setPollInterval(v === pollOffText ? null : parsePrometheusDuration(v))
}
options={pollIntervalOptions}
selected={defaultPollInterval}
title="Refresh Interval"
/>
</div>
<VariableDropdown
buttonClassName="monitoring-dashboards__dropdown"
onChange={(v: string) => setTimespan(parsePrometheusDuration(v))}
options={timespanOptions}
selected={defaultTimespan}
title="Time Range"
/>
<VariableDropdown
onChange={(v: string) =>
setPollInterval(v === pollOffText ? null : parsePrometheusDuration(v))
}
options={pollIntervalOptions}
selected={defaultPollInterval}
title="Refresh Interval"
/>
</div>
<h1 className="co-m-pane__heading">Dashboards</h1>
<div className="monitoring-dashboards__variables">
<VariableDropdown
onChange={onBoardChange}
options={boards}
selected={board}
title="Board Type"
/>
<AllVariableDropdowns />
</div>
</div>
<Dashboard>
{board && (
<Board
board={board}
patchVariable={patchVariable}
pollInterval={pollInterval}
timespan={timespan}
/>
)}
<Board
board={board}
patchVariable={patchVariable}
pollInterval={pollInterval}
timespan={timespan}
/>
</Dashboard>
</>
);
Expand Down Expand Up @@ -350,6 +355,7 @@ type CardProps = {
type MonitoringDashboardsPageProps = {
clearVariables: () => undefined;
patchVariable: (key: string, patch: Variable) => undefined;
match: any;
};

export default withFallback(MonitoringDashboardsPage, ErrorBoundaryFallback);