summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaura Montemayor <lmontemayor@gitlab.com>2019-08-14 22:57:33 +0000
committerClement Ho <408677-ClemMakesApps@users.noreply.gitlab.com>2019-08-14 22:57:33 +0000
commit9e75711aead6c5991ea116a9326762d58b91b18b (patch)
tree25cc9fbfd266f54c529da25d6c966932bee898d9
parent0b43c1027f712567d654c3e61c6557db1f4e2faa (diff)
downloadgitlab-ce-9e75711aead6c5991ea116a9326762d58b91b18b.tar.gz
Adds download CSV functionality to dropdown in metrics
This MR adds the functionality to download metrics data as CSV. It also removes the exportMetricsToCsvEnabled feature flag which was used before the dropdown was implemented to display a button.
-rw-r--r--app/assets/javascripts/monitoring/components/charts/area.vue27
-rw-r--r--app/assets/javascripts/monitoring/components/dashboard.vue17
-rw-r--r--app/assets/javascripts/monitoring/components/panel_type.vue28
-rw-r--r--app/assets/javascripts/monitoring/monitoring_bundle.js1
-rw-r--r--app/assets/javascripts/monitoring/stores/actions.js8
-rw-r--r--app/assets/javascripts/monitoring/stores/mutation_types.js1
-rw-r--r--app/assets/javascripts/monitoring/stores/mutations.js3
-rw-r--r--app/assets/javascripts/monitoring/stores/state.js1
-rw-r--r--app/controllers/projects/environments_controller.rb1
-rw-r--r--changelogs/unreleased/64950-move-download-csv-button-functionality-in-metrics-dashboard-cards-i.yml5
-rw-r--r--spec/javascripts/monitoring/charts/area_spec.js29
-rw-r--r--spec/javascripts/monitoring/dashboard_spec.js35
12 files changed, 83 insertions, 73 deletions
diff --git a/app/assets/javascripts/monitoring/components/charts/area.vue b/app/assets/javascripts/monitoring/components/charts/area.vue
index 5b950f8c966..838447e6c75 100644
--- a/app/assets/javascripts/monitoring/components/charts/area.vue
+++ b/app/assets/javascripts/monitoring/components/charts/area.vue
@@ -1,7 +1,6 @@
<script>
import { __ } from '~/locale';
-import { mapState } from 'vuex';
-import { GlLink, GlButton } from '@gitlab/ui';
+import { GlLink } from '@gitlab/ui';
import { GlAreaChart, GlChartSeriesLabel } from '@gitlab/ui/dist/charts';
import dateFormat from 'dateformat';
import { debounceByAnimationFrame, roundOffFloat } from '~/lib/utils/common_utils';
@@ -16,7 +15,6 @@ let debouncedResize;
export default {
components: {
GlAreaChart,
- GlButton,
GlChartSeriesLabel,
GlLink,
Icon,
@@ -69,7 +67,6 @@ export default {
};
},
computed: {
- ...mapState('monitoringDashboard', ['exportMetricsToCsvEnabled']),
chartData() {
// Transforms & supplements query data to render appropriate labels & styles
// Input: [{ queryAttributes1 }, { queryAttributes2 }]
@@ -179,18 +176,6 @@ export default {
yAxisLabel() {
return `${this.graphData.y_label}`;
},
- csvText() {
- const chartData = this.chartData[0].data;
- const header = `timestamp,${this.graphData.y_label}\r\n`; // eslint-disable-line @gitlab/i18n/no-non-i18n-strings
- return chartData.reduce((csv, data) => {
- const row = data.join(',');
- return `${csv}${row}\r\n`;
- }, header);
- },
- downloadLink() {
- const data = new Blob([this.csvText], { type: 'text/plain' });
- return window.URL.createObjectURL(data);
- },
},
watch: {
containerWidth: 'onResize',
@@ -259,16 +244,6 @@ export default {
<div :class="{ 'prometheus-graph-embed w-100 p-3': showBorder }">
<div class="prometheus-graph-header">
<h5 ref="graphTitle" class="prometheus-graph-title">{{ graphData.title }}</h5>
- <gl-button
- v-if="exportMetricsToCsvEnabled"
- :href="downloadLink"
- :title="__('Download CSV')"
- :aria-label="__('Download CSV')"
- style="margin-left: 200px;"
- download="chart_metrics.csv"
- >
- {{ __('Download CSV') }}
- </gl-button>
<div ref="graphWidgets" class="prometheus-graph-widgets"><slot></slot></div>
</div>
<gl-area-chart
diff --git a/app/assets/javascripts/monitoring/components/dashboard.vue b/app/assets/javascripts/monitoring/components/dashboard.vue
index 782e4310f3e..587392adbc3 100644
--- a/app/assets/javascripts/monitoring/components/dashboard.vue
+++ b/app/assets/javascripts/monitoring/components/dashboard.vue
@@ -235,6 +235,19 @@ export default {
chart.metrics.some(metric => this.metricsWithData.includes(metric.metric_id)),
);
},
+ csvText(graphData) {
+ const chartData = graphData.queries[0].result[0].values;
+ const yLabel = graphData.y_label;
+ const header = `timestamp,${yLabel}\r\n`; // eslint-disable-line @gitlab/i18n/no-non-i18n-strings
+ return chartData.reduce((csv, data) => {
+ const row = data.join(',');
+ return `${csv}${row}\r\n`;
+ }, header);
+ },
+ downloadCsv(graphData) {
+ const data = new Blob([this.csvText(graphData)], { type: 'text/plain' });
+ return window.URL.createObjectURL(data);
+ },
// TODO: BEGIN, Duplicated code with panel_type until feature flag is removed
// Issue number: https://gitlab.com/gitlab-org/gitlab-ce/issues/63845
getGraphAlerts(queries) {
@@ -448,7 +461,6 @@ export default {
@setAlerts="setAlerts"
/>
<gl-dropdown
- v-if="alertWidgetAvailable"
v-gl-tooltip
class="mx-2"
toggle-class="btn btn-transparent border-0"
@@ -459,6 +471,9 @@ export default {
<template slot="button-content">
<icon name="ellipsis_v" class="text-secondary" />
</template>
+ <gl-dropdown-item :href="downloadCsv(graphData)" download="chart_metrics.csv">
+ {{ __('Download CSV') }}
+ </gl-dropdown-item>
<gl-dropdown-item
v-if="alertWidgetAvailable"
v-gl-modal="`alert-modal-${index}-${graphIndex}`"
diff --git a/app/assets/javascripts/monitoring/components/panel_type.vue b/app/assets/javascripts/monitoring/components/panel_type.vue
index 295c0851f12..3fbac71f3d7 100644
--- a/app/assets/javascripts/monitoring/components/panel_type.vue
+++ b/app/assets/javascripts/monitoring/components/panel_type.vue
@@ -1,7 +1,14 @@
<script>
import { mapState } from 'vuex';
import _ from 'underscore';
-import { GlDropdown, GlDropdownItem, GlModal, GlModalDirective } from '@gitlab/ui';
+import {
+ GlDropdown,
+ GlDropdownItem,
+ GlModal,
+ GlModalDirective,
+ GlTooltipDirective,
+} from '@gitlab/ui';
+import Icon from '~/vue_shared/components/icon.vue';
import MonitorAreaChart from './charts/area.vue';
import MonitorSingleStatChart from './charts/single_stat.vue';
import MonitorEmptyChart from './charts/empty_chart.vue';
@@ -11,12 +18,14 @@ export default {
MonitorAreaChart,
MonitorSingleStatChart,
MonitorEmptyChart,
+ Icon,
GlDropdown,
GlDropdownItem,
GlModal,
},
directives: {
GlModal: GlModalDirective,
+ GlTooltip: GlTooltipDirective,
},
props: {
graphData: {
@@ -41,6 +50,19 @@ export default {
graphDataHasMetrics() {
return this.graphData.queries[0].result.length > 0;
},
+ csvText() {
+ const chartData = this.graphData.queries[0].result[0].values;
+ const yLabel = this.graphData.y_label;
+ const header = `timestamp,${yLabel}\r\n`; // eslint-disable-line @gitlab/i18n/no-non-i18n-strings
+ return chartData.reduce((csv, data) => {
+ const row = data.join(',');
+ return `${csv}${row}\r\n`;
+ }, header);
+ },
+ downloadCsv() {
+ const data = new Blob([this.csvText], { type: 'text/plain' });
+ return window.URL.createObjectURL(data);
+ },
},
methods: {
getGraphAlerts(queries) {
@@ -81,7 +103,6 @@ export default {
@setAlerts="setAlerts"
/>
<gl-dropdown
- v-if="alertWidgetAvailable"
v-gl-tooltip
class="mx-2"
toggle-class="btn btn-transparent border-0"
@@ -92,6 +113,9 @@ export default {
<template slot="button-content">
<icon name="ellipsis_v" class="text-secondary" />
</template>
+ <gl-dropdown-item :href="downloadCsv" download="chart_metrics.csv">
+ {{ __('Download CSV') }}
+ </gl-dropdown-item>
<gl-dropdown-item v-if="alertWidgetAvailable" v-gl-modal="`alert-modal-${index}`">
{{ __('Alerts') }}
</gl-dropdown-item>
diff --git a/app/assets/javascripts/monitoring/monitoring_bundle.js b/app/assets/javascripts/monitoring/monitoring_bundle.js
index 366034becd0..c0fee1ebb99 100644
--- a/app/assets/javascripts/monitoring/monitoring_bundle.js
+++ b/app/assets/javascripts/monitoring/monitoring_bundle.js
@@ -13,7 +13,6 @@ export default (props = {}) => {
prometheusEndpointEnabled: gon.features.environmentMetricsUsePrometheusEndpoint,
multipleDashboardsEnabled: gon.features.environmentMetricsShowMultipleDashboards,
additionalPanelTypesEnabled: gon.features.environmentMetricsAdditionalPanelTypes,
- exportMetricsToCsvEnabled: gon.features.exportMetricsToCsvEnabled,
});
}
diff --git a/app/assets/javascripts/monitoring/stores/actions.js b/app/assets/javascripts/monitoring/stores/actions.js
index a9c491c7c6c..0cbad179f17 100644
--- a/app/assets/javascripts/monitoring/stores/actions.js
+++ b/app/assets/javascripts/monitoring/stores/actions.js
@@ -37,17 +37,11 @@ export const setEndpoints = ({ commit }, endpoints) => {
export const setFeatureFlags = (
{ commit },
- {
- prometheusEndpointEnabled,
- multipleDashboardsEnabled,
- additionalPanelTypesEnabled,
- exportMetricsToCsvEnabled,
- },
+ { prometheusEndpointEnabled, multipleDashboardsEnabled, additionalPanelTypesEnabled },
) => {
commit(types.SET_DASHBOARD_ENABLED, prometheusEndpointEnabled);
commit(types.SET_MULTIPLE_DASHBOARDS_ENABLED, multipleDashboardsEnabled);
commit(types.SET_ADDITIONAL_PANEL_TYPES_ENABLED, additionalPanelTypesEnabled);
- commit(types.SET_EXPORT_METRICS_TO_CSV_ENABLED, exportMetricsToCsvEnabled);
};
export const setShowErrorBanner = ({ commit }, enabled) => {
diff --git a/app/assets/javascripts/monitoring/stores/mutation_types.js b/app/assets/javascripts/monitoring/stores/mutation_types.js
index 9ec8214b167..4b1aadbcf05 100644
--- a/app/assets/javascripts/monitoring/stores/mutation_types.js
+++ b/app/assets/javascripts/monitoring/stores/mutation_types.js
@@ -17,4 +17,3 @@ export const SET_ENDPOINTS = 'SET_ENDPOINTS';
export const SET_GETTING_STARTED_EMPTY_STATE = 'SET_GETTING_STARTED_EMPTY_STATE';
export const SET_NO_DATA_EMPTY_STATE = 'SET_NO_DATA_EMPTY_STATE';
export const SET_SHOW_ERROR_BANNER = 'SET_SHOW_ERROR_BANNER';
-export const SET_EXPORT_METRICS_TO_CSV_ENABLED = 'SET_EXPORT_METRICS_TO_CSV_ENABLED';
diff --git a/app/assets/javascripts/monitoring/stores/mutations.js b/app/assets/javascripts/monitoring/stores/mutations.js
index a2dceb21fc0..b19520d6638 100644
--- a/app/assets/javascripts/monitoring/stores/mutations.js
+++ b/app/assets/javascripts/monitoring/stores/mutations.js
@@ -99,7 +99,4 @@ export default {
[types.SET_SHOW_ERROR_BANNER](state, enabled) {
state.showErrorBanner = enabled;
},
- [types.SET_EXPORT_METRICS_TO_CSV_ENABLED](state, enabled) {
- state.exportMetricsToCsvEnabled = enabled;
- },
};
diff --git a/app/assets/javascripts/monitoring/stores/state.js b/app/assets/javascripts/monitoring/stores/state.js
index a14a25e3a20..440bdc951e0 100644
--- a/app/assets/javascripts/monitoring/stores/state.js
+++ b/app/assets/javascripts/monitoring/stores/state.js
@@ -10,7 +10,6 @@ export default () => ({
useDashboardEndpoint: false,
multipleDashboardsEnabled: false,
additionalPanelTypesEnabled: false,
- exportMetricsToCsvEnabled: false,
emptyState: 'gettingStarted',
showEmptyState: true,
showErrorBanner: true,
diff --git a/app/controllers/projects/environments_controller.rb b/app/controllers/projects/environments_controller.rb
index df9e55fda2a..5a1f93dc609 100644
--- a/app/controllers/projects/environments_controller.rb
+++ b/app/controllers/projects/environments_controller.rb
@@ -15,7 +15,6 @@ class Projects::EnvironmentsController < Projects::ApplicationController
push_frontend_feature_flag(:environment_metrics_show_multiple_dashboards)
push_frontend_feature_flag(:environment_metrics_additional_panel_types)
push_frontend_feature_flag(:prometheus_computed_alerts)
- push_frontend_feature_flag(:export_metrics_to_csv_enabled)
end
def index
diff --git a/changelogs/unreleased/64950-move-download-csv-button-functionality-in-metrics-dashboard-cards-i.yml b/changelogs/unreleased/64950-move-download-csv-button-functionality-in-metrics-dashboard-cards-i.yml
new file mode 100644
index 00000000000..21771c76873
--- /dev/null
+++ b/changelogs/unreleased/64950-move-download-csv-button-functionality-in-metrics-dashboard-cards-i.yml
@@ -0,0 +1,5 @@
+---
+title: 'feat: adds a download to csv functionality to the dropdown in prometheus metrics'
+merge_request: 31679
+author:
+type: changed
diff --git a/spec/javascripts/monitoring/charts/area_spec.js b/spec/javascripts/monitoring/charts/area_spec.js
index 4541119dd2e..57f99a09002 100644
--- a/spec/javascripts/monitoring/charts/area_spec.js
+++ b/spec/javascripts/monitoring/charts/area_spec.js
@@ -24,7 +24,6 @@ describe('Area component', () => {
store.commit(`monitoringDashboard/${types.RECEIVE_METRICS_DATA_SUCCESS}`, MonitoringMock.data);
store.commit(`monitoringDashboard/${types.RECEIVE_DEPLOYMENTS_DATA_SUCCESS}`, deploymentData);
- store.dispatch('monitoringDashboard/setFeatureFlags', { exportMetricsToCsvEnabled: true });
[mockGraphData] = store.state.monitoringDashboard.groups[0].metrics;
areaChart = shallowMount(Area, {
@@ -109,16 +108,6 @@ describe('Area component', () => {
});
});
- describe('when exportMetricsToCsvEnabled is disabled', () => {
- beforeEach(() => {
- store.dispatch('monitoringDashboard/setFeatureFlags', { exportMetricsToCsvEnabled: false });
- });
-
- it('does not render the Download CSV button', () => {
- expect(areaChart.contains('glbutton-stub')).toBe(false);
- });
- });
-
describe('methods', () => {
describe('formatTooltipText', () => {
const mockDate = deploymentData[0].created_at;
@@ -264,23 +253,5 @@ describe('Area component', () => {
expect(areaChart.vm.yAxisLabel).toBe('CPU');
});
});
-
- describe('csvText', () => {
- it('converts data from json to csv', () => {
- const header = `timestamp,${mockGraphData.y_label}`;
- const data = mockGraphData.queries[0].result[0].values;
- const firstRow = `${data[0][0]},${data[0][1]}`;
-
- expect(areaChart.vm.csvText).toMatch(`^${header}\r\n${firstRow}`);
- });
- });
-
- describe('downloadLink', () => {
- it('produces a link to download metrics as csv', () => {
- const link = areaChart.vm.downloadLink;
-
- expect(link).toContain('blob:');
- });
- });
});
});
diff --git a/spec/javascripts/monitoring/dashboard_spec.js b/spec/javascripts/monitoring/dashboard_spec.js
index 36f650d5933..b78896c45fc 100644
--- a/spec/javascripts/monitoring/dashboard_spec.js
+++ b/spec/javascripts/monitoring/dashboard_spec.js
@@ -5,7 +5,7 @@ import { timeWindows, timeWindowsKeyNames } from '~/monitoring/constants';
import * as types from '~/monitoring/stores/mutation_types';
import { createStore } from '~/monitoring/stores';
import axios from '~/lib/utils/axios_utils';
-import {
+import MonitoringMock, {
metricsGroupsAPIResponse,
mockApiEndpoint,
environmentData,
@@ -40,6 +40,7 @@ describe('Dashboard', () => {
let mock;
let store;
let component;
+ let mockGraphData;
beforeEach(() => {
setFixtures(`
@@ -482,4 +483,36 @@ describe('Dashboard', () => {
});
});
});
+
+ describe('when downloading metrics data as CSV', () => {
+ beforeEach(() => {
+ component = new DashboardComponent({
+ propsData: {
+ ...propsData,
+ },
+ store,
+ });
+ store.commit(
+ `monitoringDashboard/${types.RECEIVE_METRICS_DATA_SUCCESS}`,
+ MonitoringMock.data,
+ );
+ [mockGraphData] = component.$store.state.monitoringDashboard.groups[0].metrics;
+ });
+
+ describe('csvText', () => {
+ it('converts metrics data from json to csv', () => {
+ const header = `timestamp,${mockGraphData.y_label}`;
+ const data = mockGraphData.queries[0].result[0].values;
+ const firstRow = `${data[0][0]},${data[0][1]}`;
+
+ expect(component.csvText(mockGraphData)).toMatch(`^${header}\r\n${firstRow}`);
+ });
+ });
+
+ describe('downloadCsv', () => {
+ it('produces a link with a Blob', () => {
+ expect(component.downloadCsv(mockGraphData)).toContain(`blob:`);
+ });
+ });
+ });
});