summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClement Ho <408677-ClemMakesApps@users.noreply.gitlab.com>2019-07-24 03:18:57 +0000
committerClement Ho <408677-ClemMakesApps@users.noreply.gitlab.com>2019-07-24 03:18:57 +0000
commitc47412d48369c5e2becb2a7ce786aac73d0b325c (patch)
treec5c4e7088f551e0ffb4a74dc7a4c2341f0ede4a0
parent974bb23f8f3c2f222e9009d8ad62ab3c20fad0d1 (diff)
parent378c507cbcd4acec60fc5dadea499e6b16caa801 (diff)
downloadgitlab-ce-c47412d48369c5e2becb2a7ce786aac73d0b325c.tar.gz
Merge branch 'jivanvl-add-chart-empty-state' into 'master'
Add empty chart component Closes #60947 See merge request gitlab-org/gitlab-ce!30682
-rw-r--r--app/assets/javascripts/monitoring/components/charts/empty_chart.vue41
-rw-r--r--app/assets/javascripts/monitoring/components/dashboard.vue11
-rw-r--r--app/assets/javascripts/monitoring/components/graph_group.vue6
-rw-r--r--app/assets/javascripts/monitoring/components/panel_type.vue13
-rw-r--r--changelogs/unreleased/jivanvl-add-chart-empty-state.yml5
-rw-r--r--locale/gitlab.pot3
-rw-r--r--spec/javascripts/monitoring/charts/empty_chart_spec.js29
-rw-r--r--spec/javascripts/monitoring/panel_type_spec.js44
8 files changed, 144 insertions, 8 deletions
diff --git a/app/assets/javascripts/monitoring/components/charts/empty_chart.vue b/app/assets/javascripts/monitoring/components/charts/empty_chart.vue
new file mode 100644
index 00000000000..73682adc4ee
--- /dev/null
+++ b/app/assets/javascripts/monitoring/components/charts/empty_chart.vue
@@ -0,0 +1,41 @@
+<script>
+import chartEmptyStateIllustration from '@gitlab/svgs/dist/illustrations/chart-empty-state.svg';
+import { chartHeight } from '../../constants';
+
+export default {
+ props: {
+ graphTitle: {
+ type: String,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ height: chartHeight,
+ };
+ },
+ computed: {
+ svgContainerStyle() {
+ return {
+ height: `${this.height}px`,
+ };
+ },
+ },
+ created() {
+ this.chartEmptyStateIllustration = chartEmptyStateIllustration;
+ },
+};
+</script>
+<template>
+ <div class="prometheus-graph col-12 col-lg-6 d-flex flex-column justify-content-center">
+ <div class="prometheus-graph-header">
+ <h5 ref="graphTitle" class="prometheus-graph-title">{{ graphTitle }}</h5>
+ </div>
+ <div
+ class="prepend-top-8 svg-w-100 d-flex align-items-center"
+ :style="svgContainerStyle"
+ v-html="chartEmptyStateIllustration"
+ ></div>
+ <h5 class="text-center prepend-top-8">{{ __('No data to display') }}</h5>
+ </div>
+</template>
diff --git a/app/assets/javascripts/monitoring/components/dashboard.vue b/app/assets/javascripts/monitoring/components/dashboard.vue
index c7c55880040..745488255ab 100644
--- a/app/assets/javascripts/monitoring/components/dashboard.vue
+++ b/app/assets/javascripts/monitoring/components/dashboard.vue
@@ -157,9 +157,6 @@ export default {
'multipleDashboardsEnabled',
'additionalPanelTypesEnabled',
]),
- groupsWithData() {
- return this.groups.filter(group => this.chartsWithData(group.metrics).length > 0);
- },
selectedDashboardText() {
return this.currentDashboard || (this.allDashboards[0] && this.allDashboards[0].display_name);
},
@@ -256,6 +253,9 @@ export default {
setTimeWindowParameter(key) {
return `?time_window=${key}`;
},
+ groupHasData(group) {
+ return this.chartsWithData(group.metrics).length > 0;
+ },
},
addMetric: {
title: s__('Metrics|Add metric'),
@@ -369,14 +369,15 @@ export default {
</div>
<div v-if="!showEmptyState">
<graph-group
- v-for="groupData in groupsWithData"
+ v-for="groupData in groups"
:key="`${groupData.group}.${groupData.priority}`"
:name="groupData.group"
:show-panels="showPanels"
+ :collapse-group="groupHasData(groupData)"
>
<template v-if="additionalPanelTypesEnabled">
<panel-type
- v-for="(graphData, graphIndex) in chartsWithData(groupData.metrics)"
+ v-for="(graphData, graphIndex) in groupData.metrics"
:key="`panel-type-${graphIndex}`"
:graph-data="graphData"
:dashboard-width="elWidth"
diff --git a/app/assets/javascripts/monitoring/components/graph_group.vue b/app/assets/javascripts/monitoring/components/graph_group.vue
index b20ad1802f3..0f5c5b3d60f 100644
--- a/app/assets/javascripts/monitoring/components/graph_group.vue
+++ b/app/assets/javascripts/monitoring/components/graph_group.vue
@@ -10,6 +10,10 @@ export default {
required: false,
default: true,
},
+ collapseGroup: {
+ type: Boolean,
+ required: true,
+ },
},
};
</script>
@@ -19,7 +23,7 @@ export default {
<div class="card-header">
<h4>{{ name }}</h4>
</div>
- <div class="card-body prometheus-graph-group"><slot></slot></div>
+ <div v-if="collapseGroup" class="card-body prometheus-graph-group"><slot></slot></div>
</div>
<div v-else class="prometheus-graph-group"><slot></slot></div>
</template>
diff --git a/app/assets/javascripts/monitoring/components/panel_type.vue b/app/assets/javascripts/monitoring/components/panel_type.vue
index 45ee067de83..d7cd2c57871 100644
--- a/app/assets/javascripts/monitoring/components/panel_type.vue
+++ b/app/assets/javascripts/monitoring/components/panel_type.vue
@@ -3,11 +3,13 @@ import { mapState } from 'vuex';
import _ from 'underscore';
import MonitorAreaChart from './charts/area.vue';
import MonitorSingleStatChart from './charts/single_stat.vue';
+import MonitorEmptyChart from './charts/empty_chart.vue';
export default {
components: {
MonitorAreaChart,
MonitorSingleStatChart,
+ MonitorEmptyChart,
},
props: {
graphData: {
@@ -24,6 +26,9 @@ export default {
alertWidgetAvailable() {
return IS_EE && this.prometheusAlertsAvailable && this.alertsEndpoint && this.graphData;
},
+ graphDataHasMetrics() {
+ return this.graphData.queries[0].result.length > 0;
+ },
},
methods: {
getGraphAlerts(queries) {
@@ -41,9 +46,12 @@ export default {
};
</script>
<template>
- <monitor-single-stat-chart v-if="isPanelType('single-stat')" :graph-data="graphData" />
+ <monitor-single-stat-chart
+ v-if="isPanelType('single-stat') && graphDataHasMetrics"
+ :graph-data="graphData"
+ />
<monitor-area-chart
- v-else
+ v-else-if="graphDataHasMetrics"
:graph-data="graphData"
:deployment-data="deploymentData"
:project-path="projectPath"
@@ -59,4 +67,5 @@ export default {
@setAlerts="setAlerts"
/>
</monitor-area-chart>
+ <monitor-empty-chart v-else :graph-title="graphData.title" />
</template>
diff --git a/changelogs/unreleased/jivanvl-add-chart-empty-state.yml b/changelogs/unreleased/jivanvl-add-chart-empty-state.yml
new file mode 100644
index 00000000000..7b81ee82582
--- /dev/null
+++ b/changelogs/unreleased/jivanvl-add-chart-empty-state.yml
@@ -0,0 +1,5 @@
+---
+title: Add empty chart component
+merge_request: 30682
+author:
+type: fixed
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 5cd9aa7e2de..df53015390c 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -6917,6 +6917,9 @@ msgstr ""
msgid "No data found"
msgstr ""
+msgid "No data to display"
+msgstr ""
+
msgid "No details available"
msgstr ""
diff --git a/spec/javascripts/monitoring/charts/empty_chart_spec.js b/spec/javascripts/monitoring/charts/empty_chart_spec.js
new file mode 100644
index 00000000000..bbfca27dc5a
--- /dev/null
+++ b/spec/javascripts/monitoring/charts/empty_chart_spec.js
@@ -0,0 +1,29 @@
+import { shallowMount } from '@vue/test-utils';
+import EmptyChart from '~/monitoring/components/charts/empty_chart.vue';
+
+describe('Empty Chart component', () => {
+ let emptyChart;
+ const graphTitle = 'Memory Usage';
+
+ beforeEach(() => {
+ emptyChart = shallowMount(EmptyChart, {
+ propsData: {
+ graphTitle,
+ },
+ });
+ });
+
+ afterEach(() => {
+ emptyChart.destroy();
+ });
+
+ it('render the chart title', () => {
+ expect(emptyChart.find({ ref: 'graphTitle' }).text()).toBe(graphTitle);
+ });
+
+ describe('Computed props', () => {
+ it('sets the height for the svg container', () => {
+ expect(emptyChart.vm.svgContainerStyle.height).toBe('300px');
+ });
+ });
+});
diff --git a/spec/javascripts/monitoring/panel_type_spec.js b/spec/javascripts/monitoring/panel_type_spec.js
new file mode 100644
index 00000000000..8ce24041e97
--- /dev/null
+++ b/spec/javascripts/monitoring/panel_type_spec.js
@@ -0,0 +1,44 @@
+import { shallowMount } from '@vue/test-utils';
+import PanelType from '~/monitoring/components/panel_type.vue';
+import EmptyChart from '~/monitoring/components/charts/empty_chart.vue';
+import { graphDataPrometheusQueryRange } from './mock_data';
+
+describe('Panel Type component', () => {
+ let panelType;
+ const dashboardWidth = 100;
+
+ describe('When no graphData is available', () => {
+ let glEmptyChart;
+ const graphDataNoResult = graphDataPrometheusQueryRange;
+ graphDataNoResult.queries[0].result = [];
+
+ beforeEach(() => {
+ panelType = shallowMount(PanelType, {
+ propsData: {
+ dashboardWidth,
+ graphData: graphDataNoResult,
+ },
+ });
+ });
+
+ afterEach(() => {
+ panelType.destroy();
+ });
+
+ describe('Empty Chart component', () => {
+ beforeEach(() => {
+ glEmptyChart = panelType.find(EmptyChart);
+ });
+
+ it('is a Vue instance', () => {
+ expect(glEmptyChart.isVueInstance()).toBe(true);
+ });
+
+ it('it receives a graph title', () => {
+ const props = glEmptyChart.props();
+
+ expect(props.graphTitle).toBe(panelType.vm.graphData.title);
+ });
+ });
+ });
+});