Commit 7c5cfb4d authored by Jose Ivan Vargas's avatar Jose Ivan Vargas

Merge branch '222264-context-menu-single-stat' into 'master'

Add contextual menu to single stat panels

Closes #222264

See merge request gitlab-org/gitlab!34497
parents 2cd73372 a7026f24
...@@ -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,23 +233,32 @@ describe('Dashboard Panel', () => { ...@@ -233,23 +233,32 @@ 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' };
createWrapper({ graphData: data }, { attrs });
expect(wrapper.find(component).exists()).toBe(true); beforeEach(() => {
expect(wrapper.find(component).isVueInstance()).toBe(true); createWrapper({ graphData: data }, { attrs });
expect(wrapper.find(component).attributes()).toMatchObject(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 = { ...@@ -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