Commit bcd938d2 authored by Miguel Rincon's avatar Miguel Rincon

Update vuex usage in dashboard

- Remove auto-sorting of metrics
- Added remove metrics functionality via vuex
- Add changelog file
- Update specs
parent 97742073
......@@ -291,10 +291,17 @@ export default {
this.$toast.show(__('Link copied'));
},
// TODO: END
removeGraph(metrics, graphIndex) {
// At present graphs will not be removed, they should removed using the vuex store
// See https://gitlab.com/gitlab-org/gitlab/issues/27835
metrics.splice(graphIndex, 1);
updateMetrics(key, metrics) {
this.setPanelGroupMetrics({
metrics,
key,
});
},
removeMetric(key, metrics, graphIndex) {
this.setPanelGroupMetrics({
metrics: metrics.filter((v, i) => i !== graphIndex),
key,
});
},
showInvalidDateError() {
createFlash(s__('Metrics|Link contains an invalid time window.'));
......@@ -329,13 +336,6 @@ export default {
},
downloadCSVOptions,
generateLinkToChartOptions,
updateMetricsOrder(metrics, key) {
this.setPanelGroupMetrics({
metrics,
key,
});
},
},
addMetric: {
title: s__('Metrics|Add metric'),
......@@ -485,14 +485,14 @@ export default {
<template v-if="additionalPanelTypesEnabled">
<vue-draggable
:value="groupData.metrics"
group="metrics-dashboard"
:component-data="{ attrs: { class: 'row mx-0 w-100' } }"
:disabled="!isRearrangingPanels"
group="metrics-dashboard"
@input="updateMetricsOrder($event, groupData.key)"
@input="updateMetrics(groupData.key, $event)"
>
<div
v-for="(graphData, graphIndex) in groupData.metrics"
:key="`panel-type-${graphData}-${graphData.title}`"
:key="`panel-type-${graphIndex}`"
class="col-12 col-lg-6 px-2 mb-2 draggable"
:class="{ 'draggable-enabled': isRearrangingPanels }"
>
......@@ -500,7 +500,7 @@ export default {
<div
v-if="isRearrangingPanels"
class="draggable-remove js-draggable-remove p-2 w-100 position-absolute d-flex justify-content-end"
@click="removeGraph(groupData.metrics, graphIndex)"
@click="removeMetric(groupData.key, groupData.metrics, graphIndex)"
>
<a class="mx-2 p-2 draggable-remove-link" :aria-label="__('Remove')"
><icon name="close"
......
import Vue from 'vue';
import { slugify } from '~/lib/utils/text_utility';
import * as types from './mutation_types';
import { normalizeMetrics, sortMetrics, normalizeMetric, normalizeQueryResult } from './utils';
import { normalizeMetrics, normalizeMetric, normalizeQueryResult } from './utils';
const normalizePanel = panel => panel.metrics.map(normalizeMetric);
......@@ -11,8 +11,9 @@ export default {
state.showEmptyState = true;
},
[types.RECEIVE_METRICS_DATA_SUCCESS](state, groupData) {
state.dashboard.panel_groups = groupData.map((panelGroup, i) => {
let { metrics = [], panels = [] } = panelGroup;
state.dashboard.panel_groups = groupData.map((group, i) => {
const key = `${slugify(group.group)}-${i}`;
let { metrics = [], panels = [] } = group;
// each panel has metric information that needs to be normalized
......@@ -32,10 +33,10 @@ export default {
}
return {
...panelGroup,
...group,
panels,
key: `${slugify(panelGroup.group)}-${i}`,
metrics: normalizeMetrics(sortMetrics(metrics)),
key,
metrics: normalizeMetrics(metrics),
};
});
......
......@@ -12,8 +12,6 @@ export default () => ({
emptyState: 'gettingStarted',
showEmptyState: true,
showErrorBanner: true,
// groups stores all the dashboard!
// TODO Create an "original dashboard" data structure
dashboard: {
panel_groups: [],
},
......
......@@ -82,13 +82,6 @@ export const normalizeMetric = (metric = {}) =>
'id',
);
// TODO Fully remove this
export const sortMetrics = metrics =>
_.chain(metrics)
// .sortBy('title')
// .sortBy('weight')
.value();
export const normalizeQueryResult = timeSeries => {
let normalizedResult = {};
......
---
title: Save dashboard changes by the user into the vuex store
merge_request: 18862
author:
type: changed
......@@ -442,6 +442,28 @@ describe('Dashboard', () => {
expect(findEnabledDraggables()).toEqual(findDraggables());
});
it('metrics can be swapped', done => {
const firstDraggable = findDraggables().at(0);
const mockMetrics = [...metricsGroupsAPIResponse.data[0].metrics];
const value = () => firstDraggable.props('value');
expect(value().length).toBe(mockMetrics.length);
value().forEach((metric, i) => {
expect(metric.title).toBe(mockMetrics[i].title);
});
// swap two elements and `input` them
[mockMetrics[0], mockMetrics[1]] = [mockMetrics[1], mockMetrics[0]];
firstDraggable.vm.$emit('input', mockMetrics);
firstDraggable.vm.$nextTick(() => {
value().forEach((metric, i) => {
expect(metric.title).toBe(mockMetrics[i].title);
});
done();
});
});
it('shows a remove button, which removes a panel', done => {
expect(findFirstDraggableRemoveButton().isEmpty()).toBe(false);
......@@ -449,8 +471,6 @@ describe('Dashboard', () => {
findFirstDraggableRemoveButton().trigger('click');
wrapper.vm.$nextTick(() => {
// At present graphs will not be removed in backend
// See https://gitlab.com/gitlab-org/gitlab/issues/27835
expect(findDraggablePanels().length).toEqual(expectedPanelCount - 1);
done();
});
......@@ -661,7 +681,9 @@ describe('Dashboard', () => {
`monitoringDashboard/${types.RECEIVE_METRICS_DATA_SUCCESS}`,
MonitoringMock.data,
);
[mockGraphData] = component.$store.state.monitoringDashboard.groups[0].metrics;
[
mockGraphData,
] = component.$store.state.monitoringDashboard.dashboard.panel_groups[0].metrics;
});
describe('csvText', () => {
......
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