Commit 6d33980e authored by Martin Wortschack's avatar Martin Wortschack

Merge branch '33268-updated-operations-metrics-charts-do-not-load-properly' into 'master'

Fix empty charts in collapsed sections

Closes #33268

See merge request gitlab-org/gitlab!18699
parents c392490a 907fc48b
<script> <script>
import { s__, __ } from '~/locale'; import { s__, __ } from '~/locale';
import { GlLink, GlButton, GlTooltip } from '@gitlab/ui'; import { GlLink, GlButton, GlTooltip, GlResizeObserverDirective } from '@gitlab/ui';
import { GlAreaChart, GlLineChart, GlChartSeriesLabel } from '@gitlab/ui/dist/charts'; import { GlAreaChart, GlLineChart, GlChartSeriesLabel } from '@gitlab/ui/dist/charts';
import dateFormat from 'dateformat'; import dateFormat from 'dateformat';
import { debounceByAnimationFrame, roundOffFloat } from '~/lib/utils/common_utils'; import { roundOffFloat } from '~/lib/utils/common_utils';
import { getSvgIconPathContent } from '~/lib/utils/icon_utils'; import { getSvgIconPathContent } from '~/lib/utils/icon_utils';
import Icon from '~/vue_shared/components/icon.vue'; import Icon from '~/vue_shared/components/icon.vue';
import { chartHeight, graphTypes, lineTypes, symbolSizes, dateFormats } from '../../constants'; import { chartHeight, graphTypes, lineTypes, symbolSizes, dateFormats } from '../../constants';
import { makeDataSeries } from '~/helpers/monitor_helper'; import { makeDataSeries } from '~/helpers/monitor_helper';
import { graphDataValidatorForValues } from '../../utils'; import { graphDataValidatorForValues } from '../../utils';
let debouncedResize;
export default { export default {
components: { components: {
GlAreaChart, GlAreaChart,
...@@ -22,6 +20,9 @@ export default { ...@@ -22,6 +20,9 @@ export default {
GlLink, GlLink,
Icon, Icon,
}, },
directives: {
GlResizeObserverDirective,
},
inheritAttrs: false, inheritAttrs: false,
props: { props: {
graphData: { graphData: {
...@@ -29,10 +30,6 @@ export default { ...@@ -29,10 +30,6 @@ export default {
required: true, required: true,
validator: graphDataValidatorForValues.bind(null, false), validator: graphDataValidatorForValues.bind(null, false),
}, },
containerWidth: {
type: Number,
required: true,
},
deploymentData: { deploymentData: {
type: Array, type: Array,
required: false, required: false,
...@@ -206,21 +203,13 @@ export default { ...@@ -206,21 +203,13 @@ export default {
return `${this.graphData.y_label}`; return `${this.graphData.y_label}`;
}, },
}, },
watch: {
containerWidth: 'onResize',
},
mounted() { mounted() {
const graphTitleEl = this.$refs.graphTitle; const graphTitleEl = this.$refs.graphTitle;
if (graphTitleEl && graphTitleEl.scrollWidth > graphTitleEl.offsetWidth) { if (graphTitleEl && graphTitleEl.scrollWidth > graphTitleEl.offsetWidth) {
this.showTitleTooltip = true; this.showTitleTooltip = true;
} }
}, },
beforeDestroy() {
window.removeEventListener('resize', debouncedResize);
},
created() { created() {
debouncedResize = debounceByAnimationFrame(this.onResize);
window.addEventListener('resize', debouncedResize);
this.setSvg('rocket'); this.setSvg('rocket');
this.setSvg('scroll-handle'); this.setSvg('scroll-handle');
}, },
...@@ -276,7 +265,7 @@ export default { ...@@ -276,7 +265,7 @@ export default {
</script> </script>
<template> <template>
<div class="prometheus-graph"> <div v-gl-resize-observer-directive="onResize" class="prometheus-graph">
<div class="prometheus-graph-header"> <div class="prometheus-graph-header">
<h5 <h5
ref="graphTitle" ref="graphTitle"
......
...@@ -22,12 +22,9 @@ import MonitorTimeSeriesChart from './charts/time_series.vue'; ...@@ -22,12 +22,9 @@ import MonitorTimeSeriesChart from './charts/time_series.vue';
import MonitorSingleStatChart from './charts/single_stat.vue'; import MonitorSingleStatChart from './charts/single_stat.vue';
import GraphGroup from './graph_group.vue'; import GraphGroup from './graph_group.vue';
import EmptyState from './empty_state.vue'; import EmptyState from './empty_state.vue';
import { sidebarAnimationDuration } from '../constants';
import TrackEventDirective from '~/vue_shared/directives/track_event'; import TrackEventDirective from '~/vue_shared/directives/track_event';
import { getTimeDiff, isValidDate, downloadCSVOptions, generateLinkToChartOptions } from '../utils'; import { getTimeDiff, isValidDate, downloadCSVOptions, generateLinkToChartOptions } from '../utils';
let sidebarMutationObserver;
export default { export default {
components: { components: {
VueDraggable, VueDraggable,
...@@ -167,7 +164,6 @@ export default { ...@@ -167,7 +164,6 @@ export default {
data() { data() {
return { return {
state: 'gettingStarted', state: 'gettingStarted',
elWidth: 0,
formIsValid: null, formIsValid: null,
selectedTimeWindow: {}, selectedTimeWindow: {},
isRearrangingPanels: false, isRearrangingPanels: false,
...@@ -214,11 +210,6 @@ export default { ...@@ -214,11 +210,6 @@ export default {
projectPath: this.projectPath, projectPath: this.projectPath,
}); });
}, },
beforeDestroy() {
if (sidebarMutationObserver) {
sidebarMutationObserver.disconnect();
}
},
mounted() { mounted() {
if (!this.hasMetrics) { if (!this.hasMetrics) {
this.setGettingStartedEmptyState(); this.setGettingStartedEmptyState();
...@@ -239,13 +230,6 @@ export default { ...@@ -239,13 +230,6 @@ export default {
} else { } else {
this.fetchData(range); this.fetchData(range);
} }
sidebarMutationObserver = new MutationObserver(this.onSidebarMutation);
sidebarMutationObserver.observe(document.querySelector('.layout-page'), {
attributes: true,
childList: false,
subtree: false,
});
} }
}, },
methods: { methods: {
...@@ -306,11 +290,6 @@ export default { ...@@ -306,11 +290,6 @@ export default {
hideAddMetricModal() { hideAddMetricModal() {
this.$refs.addMetricModal.hide(); this.$refs.addMetricModal.hide();
}, },
onSidebarMutation() {
setTimeout(() => {
this.elWidth = this.$el.clientWidth;
}, sidebarAnimationDuration);
},
toggleRearrangingPanels() { toggleRearrangingPanels() {
this.isRearrangingPanels = !this.isRearrangingPanels; this.isRearrangingPanels = !this.isRearrangingPanels;
}, },
...@@ -503,7 +482,6 @@ export default { ...@@ -503,7 +482,6 @@ export default {
generateLink(groupData.group, graphData.title, graphData.y_label) generateLink(groupData.group, graphData.title, graphData.y_label)
" "
:graph-data="graphData" :graph-data="graphData"
:dashboard-width="elWidth"
:alerts-endpoint="alertsEndpoint" :alerts-endpoint="alertsEndpoint"
:prometheus-alerts-available="prometheusAlertsAvailable" :prometheus-alerts-available="prometheusAlertsAvailable"
:index="`${index}-${graphIndex}`" :index="`${index}-${graphIndex}`"
...@@ -520,7 +498,6 @@ export default { ...@@ -520,7 +498,6 @@ export default {
:graph-data="graphData" :graph-data="graphData"
:deployment-data="deploymentData" :deployment-data="deploymentData"
:thresholds="getGraphAlertValues(graphData.queries)" :thresholds="getGraphAlertValues(graphData.queries)"
:container-width="elWidth"
:project-path="projectPath" :project-path="projectPath"
group-id="monitor-time-series-chart" group-id="monitor-time-series-chart"
> >
......
...@@ -45,7 +45,7 @@ export default { ...@@ -45,7 +45,7 @@ export default {
<div v-if="showPanels" class="card prometheus-panel"> <div v-if="showPanels" class="card prometheus-panel">
<div class="card-header d-flex align-items-center"> <div class="card-header d-flex align-items-center">
<h4 class="flex-grow-1">{{ name }}</h4> <h4 class="flex-grow-1">{{ name }}</h4>
<a role="button" @click="collapse"> <a role="button" class="js-graph-group-toggle" @click="collapse">
<icon :size="16" :aria-label="__('Toggle collapse')" :name="caretIcon" /> <icon :size="16" :aria-label="__('Toggle collapse')" :name="caretIcon" />
</a> </a>
</div> </div>
......
...@@ -40,10 +40,6 @@ export default { ...@@ -40,10 +40,6 @@ export default {
type: Object, type: Object,
required: true, required: true,
}, },
dashboardWidth: {
type: Number,
required: true,
},
index: { index: {
type: String, type: String,
required: false, required: false,
...@@ -103,7 +99,6 @@ export default { ...@@ -103,7 +99,6 @@ export default {
:deployment-data="deploymentData" :deployment-data="deploymentData"
:project-path="projectPath" :project-path="projectPath"
:thresholds="getGraphAlertValues(graphData.queries)" :thresholds="getGraphAlertValues(graphData.queries)"
:container-width="dashboardWidth"
group-id="monitor-area-chart" group-id="monitor-area-chart"
> >
<div class="d-flex align-items-center"> <div class="d-flex align-items-center">
......
---
title: Fix empty chart in collapsed sections
merge_request: 18699
author:
type: fixed
...@@ -539,42 +539,67 @@ describe('Dashboard', () => { ...@@ -539,42 +539,67 @@ describe('Dashboard', () => {
}); });
}); });
describe('when the window resizes', () => { describe('responds to window resizes', () => {
let promPanel;
let promGroup;
let panelToggle;
let chart;
beforeEach(() => { beforeEach(() => {
mock.onGet(mockApiEndpoint).reply(200, metricsGroupsAPIResponse); mock.onGet(mockApiEndpoint).reply(200, metricsGroupsAPIResponse);
jasmine.clock().install();
});
afterEach(() => {
jasmine.clock().uninstall();
});
it('sets elWidth to page width when the sidebar is resized', done => {
component = new DashboardComponent({ component = new DashboardComponent({
el: document.querySelector('.prometheus-graphs'), el: document.querySelector('.prometheus-graphs'),
propsData: { propsData: {
...propsData, ...propsData,
hasMetrics: true, hasMetrics: true,
showPanels: false, showPanels: true,
}, },
store, store,
}); });
expect(component.elWidth).toEqual(0); component.$store.dispatch('monitoringDashboard/setFeatureFlags', {
prometheusEndpoint: false,
});
const pageLayoutEl = document.querySelector('.layout-page'); component.$store.commit(
pageLayoutEl.classList.add('page-with-icon-sidebar'); `monitoringDashboard/${types.RECEIVE_ENVIRONMENTS_DATA_SUCCESS}`,
environmentData,
);
Vue.nextTick() component.$store.commit(
.then(() => { `monitoringDashboard/${types.RECEIVE_METRICS_DATA_SUCCESS}`,
jasmine.clock().tick(1000); singleGroupResponse,
return Vue.nextTick(); );
})
.then(() => { component.$store.commit(
expect(component.elWidth).toEqual(pageLayoutEl.clientWidth); `monitoringDashboard/${types.SET_ALL_DASHBOARDS}`,
done(); dashboardGitResponse,
}) );
.catch(done.fail);
return Vue.nextTick().then(() => {
promPanel = component.$el.querySelector('.prometheus-panel');
promGroup = promPanel.querySelector('.prometheus-graph-group');
panelToggle = promPanel.querySelector('.js-graph-group-toggle');
chart = promGroup.querySelector('.position-relative svg');
});
});
it('setting chart size to zero when panel group is hidden', () => {
expect(promGroup.style.display).toBe('');
expect(chart.clientWidth).toBeGreaterThan(0);
panelToggle.click();
return Vue.nextTick().then(() => {
expect(promGroup.style.display).toBe('none');
expect(chart.clientWidth).toBe(0);
promPanel.style.width = '500px';
});
});
it('expanding chart panel group after resize displays chart', () => {
panelToggle.click();
expect(chart.clientWidth).toBeGreaterThan(0);
}); });
}); });
......
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