Fix monitoring dashboard not working properly

This fixes a bug when the monitoring dashboard wouldn't redraw for when the sidebar
was collapsed/expanded on medium to small screens. This is done by enforcing vue
to update based on the change of a key
parent 7dd8d379
......@@ -97,33 +97,45 @@ export default {
store: new MonitoringStore(),
state: 'gettingStarted',
showEmptyState: true,
updateAspectRatio: false,
updatedAspectRatios: 0,
hoverData: {},
resizeThrottled: {},
updateDashboardKeyNumber: 0,
};
},
computed: {
forceRedraw() {
return `dashboard-key-${this.updateDashboardKeyNumber}`;
},
},
created() {
this.service = new MonitoringService({
metricsEndpoint: this.metricsEndpoint,
deploymentEndpoint: this.deploymentEndpoint,
environmentsEndpoint: this.environmentsEndpoint,
});
eventHub.$on('toggleAspectRatio', this.toggleAspectRatio);
this.mutationObserverConfig = {
attributes: true,
childList: false,
subtree: false,
};
eventHub.$on('hoverChanged', this.hoverChanged);
},
beforeDestroy() {
eventHub.$off('toggleAspectRatio', this.toggleAspectRatio);
eventHub.$off('hoverChanged', this.hoverChanged);
window.removeEventListener('resize', this.resizeThrottled, false);
this.sidebarMutationObserver.disconnect();
},
mounted() {
this.resizeThrottled = _.throttle(this.resize, 600);
this.resizeThrottled = _.debounce(this.resize, 100);
if (!this.hasMetrics) {
this.state = 'gettingStarted';
} else {
this.getGraphsData();
window.addEventListener('resize', this.resizeThrottled, false);
const sidebarEl = document.querySelector('.nav-sidebar');
// The sidebar listener
this.sidebarMutationObserver = new MutationObserver(this.resizeThrottled);
this.sidebarMutationObserver.observe(sidebarEl, this.mutationObserverConfig);
}
},
methods: {
......@@ -153,14 +165,7 @@ export default {
});
},
resize() {
this.updateAspectRatio = true;
},
toggleAspectRatio() {
this.updatedAspectRatios += 1;
if (this.store.getMetricsCount() === this.updatedAspectRatios) {
this.updateAspectRatio = !this.updateAspectRatio;
this.updatedAspectRatios = 0;
}
this.updateDashboardKeyNumber += 1;
},
hoverChanged(data) {
this.hoverData = data;
......@@ -172,6 +177,7 @@ export default {
<template>
<div
v-if="!showEmptyState"
:key="forceRedraw"
class="prometheus-graphs prepend-top-default"
>
<div class="environments d-flex align-items-center">
......@@ -218,7 +224,6 @@ export default {
:key="index"
:graph-data="graphData"
:hover-data="hoverData"
:update-aspect-ratio="updateAspectRatio"
:deployment-data="store.deploymentData"
:project-path="projectPath"
:tags-path="tagsPath"
......
......@@ -32,10 +32,6 @@ export default {
type: Object,
required: true,
},
updateAspectRatio: {
type: Boolean,
required: true,
},
deploymentData: {
type: Array,
required: true,
......@@ -110,15 +106,6 @@ export default {
},
},
watch: {
updateAspectRatio() {
if (this.updateAspectRatio) {
this.graphHeight = 450;
this.graphWidth = 600;
this.measurements = measurements.large;
this.draw();
eventHub.$emit('toggleAspectRatio');
}
},
hoverData() {
this.positionFlag();
},
......
---
title: Fix resizing of monitoring dashboard
merge_request: 21730
author:
type: fixed
......@@ -25,7 +25,10 @@ describe('Dashboard', () => {
};
beforeEach(() => {
setFixtures('<div class="prometheus-graphs"></div>');
setFixtures(`
<div class="prometheus-graphs"></div>
<div class="nav-sidebar"></div>
`);
DashboardComponent = Vue.extend(Dashboard);
});
......@@ -127,4 +130,41 @@ describe('Dashboard', () => {
});
});
});
describe('when the window resizes', () => {
let mock;
beforeEach(() => {
mock = new MockAdapter(axios);
mock.onGet(mockApiEndpoint).reply(200, metricsGroupsAPIResponse);
jasmine.clock().install();
});
afterEach(() => {
mock.restore();
jasmine.clock().uninstall();
});
it('rerenders the dashboard when the sidebar is resized', done => {
const component = new DashboardComponent({
el: document.querySelector('.prometheus-graphs'),
propsData: { ...propsData, hasMetrics: true, showPanels: false },
});
expect(component.forceRedraw).toEqual('dashboard-key-0');
const navSidebarEl = document.querySelector('.nav-sidebar');
navSidebarEl.classList.add('nav-sidebar-collapsed');
Vue.nextTick()
.then(() => {
jasmine.clock().tick(1000);
return Vue.nextTick();
})
.then(() => {
expect(component.forceRedraw).toEqual('dashboard-key-1');
done();
})
.catch(done.fail);
});
});
});
import Vue from 'vue';
import Graph from '~/monitoring/components/graph.vue';
import MonitoringMixins from '~/monitoring/mixins/monitoring_mixins';
import eventHub from '~/monitoring/event_hub';
import {
deploymentData,
convertDatesMultipleSeries,
......@@ -69,23 +68,6 @@ describe('Graph', () => {
});
});
it('sends an event to the eventhub when it has finished resizing', done => {
const component = createComponent({
graphData: convertedMetrics[1],
updateAspectRatio: false,
deploymentData,
tagsPath,
projectPath,
});
spyOn(eventHub, '$emit');
component.updateAspectRatio = true;
Vue.nextTick(() => {
expect(eventHub.$emit).toHaveBeenCalled();
done();
});
});
it('has a title for the y-axis and the chart legend that comes from the backend', () => {
const component = createComponent({
graphData: convertedMetrics[1],
......
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