Commit a7026f24 authored by Miguel Rincon's avatar Miguel Rincon Committed by Jose Vargas

Add contextual menu to single stat panels

Allow single stat panels to show the same contextual menu as
other time series based charts.
parent 656123d5
...@@ -17,7 +17,9 @@ const defaultTooltipFormat = defaultFormat; ...@@ -17,7 +17,9 @@ const defaultTooltipFormat = defaultFormat;
const defaultTooltipPrecision = 3; const defaultTooltipPrecision = 3;
// Give enough space for y-axis with units and name. // Give enough space for y-axis with units and name.
const chartGridLeft = 75; const chartGridLeft = 63; // larger gap than gitlab-ui's default to fit formatted numbers
const chartGridRight = 10; // half of the scroll-handle icon for data zoom
const yAxisNameGap = chartGridLeft - 12; // offset the axis label line-height
// Axis options // Axis options
...@@ -62,7 +64,7 @@ export const getYAxisOptions = ({ ...@@ -62,7 +64,7 @@ export const getYAxisOptions = ({
precision = defaultYAxisPrecision, precision = defaultYAxisPrecision,
} = {}) => { } = {}) => {
return { return {
nameGap: 63, // larger gap than gitlab-ui's default to fit with formatted numbers nameGap: yAxisNameGap,
scale: true, scale: true,
boundaryGap: yAxisBoundaryGap, boundaryGap: yAxisBoundaryGap,
...@@ -90,7 +92,10 @@ export const getTimeAxisOptions = ({ timezone = timezones.LOCAL } = {}) => ({ ...@@ -90,7 +92,10 @@ export const getTimeAxisOptions = ({ timezone = timezones.LOCAL } = {}) => ({
/** /**
* Grid with enough room to display chart. * Grid with enough room to display chart.
*/ */
export const getChartGrid = ({ left = chartGridLeft } = {}) => ({ left }); export const getChartGrid = ({ left = chartGridLeft, right = chartGridRight } = {}) => ({
left,
right,
});
// Tooltip options // Tooltip options
......
...@@ -132,7 +132,8 @@ export default { ...@@ -132,7 +132,8 @@ export default {
return this.graphData?.title || ''; return this.graphData?.title || '';
}, },
graphDataHasResult() { graphDataHasResult() {
return this.graphData?.metrics?.[0]?.result?.length > 0; const metrics = this.graphData?.metrics || [];
return metrics.some(({ result }) => result?.length > 0);
}, },
graphDataIsLoading() { graphDataIsLoading() {
const metrics = this.graphData?.metrics || []; const metrics = this.graphData?.metrics || [];
...@@ -207,7 +208,17 @@ export default { ...@@ -207,7 +208,17 @@ export default {
return MonitorTimeSeriesChart; return MonitorTimeSeriesChart;
}, },
isContextualMenuShown() { isContextualMenuShown() {
return Boolean(this.graphDataHasResult && !this.basicChartComponent); if (!this.graphDataHasResult) {
return false;
}
// Only a few charts have a contextual menu, support
// for more chart types planned at:
// https://gitlab.com/groups/gitlab-org/-/epics/3573
return (
this.isPanelType(panelTypes.AREA_CHART) ||
this.isPanelType(panelTypes.LINE_CHART) ||
this.isPanelType(panelTypes.SINGLE_STAT)
);
}, },
editCustomMetricLink() { editCustomMetricLink() {
if (this.graphData.metrics.length > 1) { if (this.graphData.metrics.length > 1) {
...@@ -223,7 +234,10 @@ export default { ...@@ -223,7 +234,10 @@ export default {
return metrics.some(({ metricId }) => this.metricsSavedToDb.includes(metricId)); return metrics.some(({ metricId }) => this.metricsSavedToDb.includes(metricId));
}, },
alertWidgetAvailable() { alertWidgetAvailable() {
const supportsAlerts =
this.isPanelType(panelTypes.AREA_CHART) || this.isPanelType(panelTypes.LINE_CHART);
return ( return (
supportsAlerts &&
this.prometheusAlertsAvailable && this.prometheusAlertsAvailable &&
this.alertsEndpoint && this.alertsEndpoint &&
this.graphData && this.graphData &&
...@@ -284,7 +298,7 @@ export default { ...@@ -284,7 +298,7 @@ export default {
</script> </script>
<template> <template>
<div v-gl-resize-observer="onResize" class="prometheus-graph"> <div v-gl-resize-observer="onResize" class="prometheus-graph">
<div class="d-flex align-items-center mr-3"> <div class="d-flex align-items-center">
<slot name="topLeft"></slot> <slot name="topLeft"></slot>
<h5 <h5
ref="graphTitle" ref="graphTitle"
...@@ -375,7 +389,7 @@ export default { ...@@ -375,7 +389,7 @@ export default {
{{ __('Alerts') }} {{ __('Alerts') }}
</gl-dropdown-item> </gl-dropdown-item>
<template v-if="graphData.links.length"> <template v-if="graphData.links && graphData.links.length">
<gl-dropdown-divider /> <gl-dropdown-divider />
<gl-dropdown-item <gl-dropdown-item
v-for="(link, index) in graphData.links" v-for="(link, index) in graphData.links"
......
---
title: Add contextual menu to single stat panels
merge_request: 34497
author:
type: changed
...@@ -233,24 +233,33 @@ describe('Dashboard Panel', () => { ...@@ -233,24 +233,33 @@ describe('Dashboard Panel', () => {
expect(wrapper.find(MonitorTimeSeriesChart).isVueInstance()).toBe(true); expect(wrapper.find(MonitorTimeSeriesChart).isVueInstance()).toBe(true);
}); });
it.each` describe.each`
data | component data | component | hasCtxMenu
${dataWithType(panelTypes.AREA_CHART)} | ${MonitorTimeSeriesChart} ${dataWithType(panelTypes.AREA_CHART)} | ${MonitorTimeSeriesChart} | ${true}
${dataWithType(panelTypes.LINE_CHART)} | ${MonitorTimeSeriesChart} ${dataWithType(panelTypes.LINE_CHART)} | ${MonitorTimeSeriesChart} | ${true}
${anomalyMockGraphData} | ${MonitorAnomalyChart} ${singleStatMetricsResult} | ${MonitorSingleStatChart} | ${true}
${dataWithType(panelTypes.COLUMN)} | ${MonitorColumnChart} ${anomalyMockGraphData} | ${MonitorAnomalyChart} | ${false}
${dataWithType(panelTypes.STACKED_COLUMN)} | ${MonitorStackedColumnChart} ${dataWithType(panelTypes.COLUMN)} | ${MonitorColumnChart} | ${false}
${singleStatMetricsResult} | ${MonitorSingleStatChart} ${dataWithType(panelTypes.STACKED_COLUMN)} | ${MonitorStackedColumnChart} | ${false}
${graphDataPrometheusQueryRangeMultiTrack} | ${MonitorHeatmapChart} ${graphDataPrometheusQueryRangeMultiTrack} | ${MonitorHeatmapChart} | ${false}
${barMockData} | ${MonitorBarChart} ${barMockData} | ${MonitorBarChart} | ${false}
`('wrapps a $data.type component binding attributes', ({ data, component }) => { `('when $data.type data is provided', ({ data, component, hasCtxMenu }) => {
const attrs = { attr1: 'attr1Value', attr2: 'attr2Value' }; const attrs = { attr1: 'attr1Value', attr2: 'attr2Value' };
beforeEach(() => {
createWrapper({ graphData: data }, { attrs }); createWrapper({ graphData: data }, { attrs });
});
it(`renders the chart component and binds attributes`, () => {
expect(wrapper.find(component).exists()).toBe(true); expect(wrapper.find(component).exists()).toBe(true);
expect(wrapper.find(component).isVueInstance()).toBe(true); expect(wrapper.find(component).isVueInstance()).toBe(true);
expect(wrapper.find(component).attributes()).toMatchObject(attrs); expect(wrapper.find(component).attributes()).toMatchObject(attrs);
}); });
it(`contextual menu is ${hasCtxMenu ? '' : 'not '}shown`, () => {
expect(findCtxMenu().exists()).toBe(hasCtxMenu);
});
});
}); });
}); });
......
...@@ -369,6 +369,7 @@ export const singleStatMetricsResult = { ...@@ -369,6 +369,7 @@ export const singleStatMetricsResult = {
{ {
metric: { job: 'prometheus' }, metric: { job: 'prometheus' },
value: ['2019-06-26T21:03:20.881Z', 91], value: ['2019-06-26T21:03:20.881Z', 91],
values: [['2019-06-26T21:03:20.881Z', 91]],
}, },
], ],
}, },
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment