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;
const defaultTooltipPrecision = 3;
// 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
......@@ -62,7 +64,7 @@ export const getYAxisOptions = ({
precision = defaultYAxisPrecision,
} = {}) => {
return {
nameGap: 63, // larger gap than gitlab-ui's default to fit with formatted numbers
nameGap: yAxisNameGap,
scale: true,
boundaryGap: yAxisBoundaryGap,
......@@ -90,7 +92,10 @@ export const getTimeAxisOptions = ({ timezone = timezones.LOCAL } = {}) => ({
/**
* Grid with enough room to display chart.
*/
export const getChartGrid = ({ left = chartGridLeft } = {}) => ({ left });
export const getChartGrid = ({ left = chartGridLeft, right = chartGridRight } = {}) => ({
left,
right,
});
// Tooltip options
......
......@@ -132,7 +132,8 @@ export default {
return this.graphData?.title || '';
},
graphDataHasResult() {
return this.graphData?.metrics?.[0]?.result?.length > 0;
const metrics = this.graphData?.metrics || [];
return metrics.some(({ result }) => result?.length > 0);
},
graphDataIsLoading() {
const metrics = this.graphData?.metrics || [];
......@@ -207,7 +208,17 @@ export default {
return MonitorTimeSeriesChart;
},
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() {
if (this.graphData.metrics.length > 1) {
......@@ -223,7 +234,10 @@ export default {
return metrics.some(({ metricId }) => this.metricsSavedToDb.includes(metricId));
},
alertWidgetAvailable() {
const supportsAlerts =
this.isPanelType(panelTypes.AREA_CHART) || this.isPanelType(panelTypes.LINE_CHART);
return (
supportsAlerts &&
this.prometheusAlertsAvailable &&
this.alertsEndpoint &&
this.graphData &&
......@@ -284,7 +298,7 @@ export default {
</script>
<template>
<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>
<h5
ref="graphTitle"
......@@ -375,7 +389,7 @@ export default {
{{ __('Alerts') }}
</gl-dropdown-item>
<template v-if="graphData.links.length">
<template v-if="graphData.links && graphData.links.length">
<gl-dropdown-divider />
<gl-dropdown-item
v-for="(link, index) in graphData.links"
......
---
title: Add contextual menu to single stat panels
merge_request: 34497
author:
type: changed
......@@ -233,23 +233,32 @@ describe('Dashboard Panel', () => {
expect(wrapper.find(MonitorTimeSeriesChart).isVueInstance()).toBe(true);
});
it.each`
data | component
${dataWithType(panelTypes.AREA_CHART)} | ${MonitorTimeSeriesChart}
${dataWithType(panelTypes.LINE_CHART)} | ${MonitorTimeSeriesChart}
${anomalyMockGraphData} | ${MonitorAnomalyChart}
${dataWithType(panelTypes.COLUMN)} | ${MonitorColumnChart}
${dataWithType(panelTypes.STACKED_COLUMN)} | ${MonitorStackedColumnChart}
${singleStatMetricsResult} | ${MonitorSingleStatChart}
${graphDataPrometheusQueryRangeMultiTrack} | ${MonitorHeatmapChart}
${barMockData} | ${MonitorBarChart}
`('wrapps a $data.type component binding attributes', ({ data, component }) => {
describe.each`
data | component | hasCtxMenu
${dataWithType(panelTypes.AREA_CHART)} | ${MonitorTimeSeriesChart} | ${true}
${dataWithType(panelTypes.LINE_CHART)} | ${MonitorTimeSeriesChart} | ${true}
${singleStatMetricsResult} | ${MonitorSingleStatChart} | ${true}
${anomalyMockGraphData} | ${MonitorAnomalyChart} | ${false}
${dataWithType(panelTypes.COLUMN)} | ${MonitorColumnChart} | ${false}
${dataWithType(panelTypes.STACKED_COLUMN)} | ${MonitorStackedColumnChart} | ${false}
${graphDataPrometheusQueryRangeMultiTrack} | ${MonitorHeatmapChart} | ${false}
${barMockData} | ${MonitorBarChart} | ${false}
`('when $data.type data is provided', ({ data, component, hasCtxMenu }) => {
const attrs = { attr1: 'attr1Value', attr2: 'attr2Value' };
createWrapper({ graphData: data }, { attrs });
expect(wrapper.find(component).exists()).toBe(true);
expect(wrapper.find(component).isVueInstance()).toBe(true);
expect(wrapper.find(component).attributes()).toMatchObject(attrs);
beforeEach(() => {
createWrapper({ graphData: data }, { attrs });
});
it(`renders the chart component and binds attributes`, () => {
expect(wrapper.find(component).exists()).toBe(true);
expect(wrapper.find(component).isVueInstance()).toBe(true);
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 = {
{
metric: { job: 'prometheus' },
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