Commit c87f587b authored by Jose Ivan Vargas's avatar Jose Ivan Vargas

Merge branch 'astoicescu/fullWidthCharts' into 'master'

Give full width to last panel in a panelGroup with odd number of panels

See merge request gitlab-org/gitlab!34999
parents bc0228c3 828de6b0
...@@ -316,6 +316,16 @@ export default { ...@@ -316,6 +316,16 @@ export default {
// As a fallback, switch to default time range instead // As a fallback, switch to default time range instead
this.selectedTimeRange = defaultTimeRange; this.selectedTimeRange = defaultTimeRange;
}, },
isPanelHalfWidth(panelIndex, totalPanels) {
/**
* A single panel on a row should take the full width of its parent.
* All others should have half the width their parent.
*/
const isNumberOfPanelsEven = totalPanels % 2 === 0;
const isLastPanel = panelIndex === totalPanels - 1;
return isNumberOfPanelsEven || !isLastPanel;
},
}, },
i18n: { i18n: {
goBackLabel: s__('Metrics|Go back (Esc)'), goBackLabel: s__('Metrics|Go back (Esc)'),
...@@ -391,8 +401,12 @@ export default { ...@@ -391,8 +401,12 @@ export default {
<div <div
v-for="(graphData, graphIndex) in groupData.panels" v-for="(graphData, graphIndex) in groupData.panels"
:key="`dashboard-panel-${graphIndex}`" :key="`dashboard-panel-${graphIndex}`"
class="col-12 col-lg-6 px-2 mb-2 draggable" data-testid="dashboard-panel-layout-wrapper"
:class="{ 'draggable-enabled': isRearrangingPanels }" class="col-12 px-2 mb-2 draggable"
:class="{
'draggable-enabled': isRearrangingPanels,
'col-lg-6': isPanelHalfWidth(graphIndex, groupData.panels.length),
}"
> >
<div class="position-relative draggable-panel js-draggable-panel"> <div class="position-relative draggable-panel js-draggable-panel">
<div <div
......
---
title: Add full width to single charts in a row
merge_request: 34999
author:
type: added
...@@ -16,6 +16,7 @@ import DashboardsDropdown from '~/monitoring/components/dashboards_dropdown.vue' ...@@ -16,6 +16,7 @@ import DashboardsDropdown from '~/monitoring/components/dashboards_dropdown.vue'
import EmptyState from '~/monitoring/components/empty_state.vue'; import EmptyState from '~/monitoring/components/empty_state.vue';
import GroupEmptyState from '~/monitoring/components/group_empty_state.vue'; import GroupEmptyState from '~/monitoring/components/group_empty_state.vue';
import DashboardPanel from '~/monitoring/components/dashboard_panel.vue'; import DashboardPanel from '~/monitoring/components/dashboard_panel.vue';
import GraphGroup from '~/monitoring/components/graph_group.vue';
import LinksSection from '~/monitoring/components/links_section.vue'; import LinksSection from '~/monitoring/components/links_section.vue';
import { createStore } from '~/monitoring/stores'; import { createStore } from '~/monitoring/stores';
import * as types from '~/monitoring/stores/mutation_types'; import * as types from '~/monitoring/stores/mutation_types';
...@@ -24,6 +25,7 @@ import { ...@@ -24,6 +25,7 @@ import {
setupStoreWithDashboard, setupStoreWithDashboard,
setMetricResult, setMetricResult,
setupStoreWithData, setupStoreWithData,
setupStoreWithDataForPanelCount,
setupStoreWithVariable, setupStoreWithVariable,
setupStoreWithLinks, setupStoreWithLinks,
} from '../store_utils'; } from '../store_utils';
...@@ -157,6 +159,75 @@ describe('Dashboard', () => { ...@@ -157,6 +159,75 @@ describe('Dashboard', () => {
}); });
}); });
describe('panel containers layout', () => {
const findPanelLayoutWrapperAt = index => {
return wrapper
.find(GraphGroup)
.findAll('[data-testid="dashboard-panel-layout-wrapper"]')
.at(index);
};
beforeEach(() => {
createMountedWrapper({ hasMetrics: true });
return wrapper.vm.$nextTick();
});
describe('when the graph group has an even number of panels', () => {
it('2 panels - all panel wrappers take half width of their parent', () => {
setupStoreWithDataForPanelCount(store, 2);
wrapper.vm.$nextTick(() => {
expect(findPanelLayoutWrapperAt(0).classes('col-lg-6')).toBe(true);
expect(findPanelLayoutWrapperAt(1).classes('col-lg-6')).toBe(true);
});
});
it('4 panels - all panel wrappers take half width of their parent', () => {
setupStoreWithDataForPanelCount(store, 4);
wrapper.vm.$nextTick(() => {
expect(findPanelLayoutWrapperAt(0).classes('col-lg-6')).toBe(true);
expect(findPanelLayoutWrapperAt(1).classes('col-lg-6')).toBe(true);
expect(findPanelLayoutWrapperAt(2).classes('col-lg-6')).toBe(true);
expect(findPanelLayoutWrapperAt(3).classes('col-lg-6')).toBe(true);
});
});
});
describe('when the graph group has an odd number of panels', () => {
it('1 panel - panel wrapper does not take half width of its parent', () => {
setupStoreWithDataForPanelCount(store, 1);
wrapper.vm.$nextTick(() => {
expect(findPanelLayoutWrapperAt(0).classes('col-lg-6')).toBe(false);
});
});
it('3 panels - all panels but last take half width of their parents', () => {
setupStoreWithDataForPanelCount(store, 3);
wrapper.vm.$nextTick(() => {
expect(findPanelLayoutWrapperAt(0).classes('col-lg-6')).toBe(true);
expect(findPanelLayoutWrapperAt(1).classes('col-lg-6')).toBe(true);
expect(findPanelLayoutWrapperAt(2).classes('col-lg-6')).toBe(false);
});
});
it('5 panels - all panels but last take half width of their parents', () => {
setupStoreWithDataForPanelCount(store, 5);
wrapper.vm.$nextTick(() => {
expect(findPanelLayoutWrapperAt(0).classes('col-lg-6')).toBe(true);
expect(findPanelLayoutWrapperAt(1).classes('col-lg-6')).toBe(true);
expect(findPanelLayoutWrapperAt(2).classes('col-lg-6')).toBe(true);
expect(findPanelLayoutWrapperAt(3).classes('col-lg-6')).toBe(true);
expect(findPanelLayoutWrapperAt(4).classes('col-lg-6')).toBe(false);
});
});
});
});
describe('dashboard validation warning', () => { describe('dashboard validation warning', () => {
it('displays a warning if there are validation warnings', () => { it('displays a warning if there are validation warnings', () => {
createMountedWrapper({ hasMetrics: true }); createMountedWrapper({ hasMetrics: true });
......
...@@ -63,3 +63,24 @@ export const setupStoreWithData = store => { ...@@ -63,3 +63,24 @@ export const setupStoreWithData = store => {
setEnvironmentData(store); setEnvironmentData(store);
}; };
export const setupStoreWithDataForPanelCount = (store, panelCount) => {
const payloadPanelGroup = metricsDashboardPayload.panel_groups[0];
const panelGroupCustom = {
...payloadPanelGroup,
panels: payloadPanelGroup.panels.slice(0, panelCount),
};
const metricsDashboardPayloadCustom = {
...metricsDashboardPayload,
panel_groups: [panelGroupCustom],
};
store.commit(
`monitoringDashboard/${types.RECEIVE_METRICS_DASHBOARD_SUCCESS}`,
metricsDashboardPayloadCustom,
);
setMetricResult({ store, result: metricsResult, panel: 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