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;
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