Commit 772c2675 authored by Brandon Labuschagne's avatar Brandon Labuschagne

Add Throughput chart error handling

The throughput chart currently does not display errors on
the frontend.

This MR introduces a nice FE error message display.
parent 8ae7daa4
......@@ -3,7 +3,7 @@ import { GlAreaChart } from '@gitlab/ui/dist/charts';
import { GlAlert, GlLoadingIcon } from '@gitlab/ui';
import { getDateInPast } from '~/lib/utils/datetime_utility';
import throughputChartQueryBuilder from '../graphql/throughput_chart_query_builder';
import { DEFAULT_NUMBER_OF_DAYS, THROUGHPUT_STRINGS } from '../constants';
import { DEFAULT_NUMBER_OF_DAYS, THROUGHPUT_CHART_STRINGS } from '../constants';
export default {
name: 'ThroughputChart',
......@@ -18,6 +18,7 @@ export default {
throughputChartData: [],
startDate: getDateInPast(new Date(), DEFAULT_NUMBER_OF_DAYS),
endDate: new Date(),
hasError: false,
};
},
apollo: {
......@@ -30,13 +31,16 @@ export default {
fullPath: this.fullPath,
};
},
error() {
this.hasError = true;
},
},
},
computed: {
chartOptions() {
return {
xAxis: {
name: THROUGHPUT_STRINGS.X_AXIS_TITLE,
name: THROUGHPUT_CHART_STRINGS.X_AXIS_TITLE,
type: 'category',
axisLabel: {
formatter: value => {
......@@ -45,33 +49,42 @@ export default {
},
},
yAxis: {
name: THROUGHPUT_STRINGS.Y_AXIS_TITLE,
name: THROUGHPUT_CHART_STRINGS.Y_AXIS_TITLE,
},
};
},
formattedThroughputChartData() {
if (!this.throughputChartData) return [];
const data = Object.keys(this.throughputChartData)
.slice(0, -1) // Remove the __typeName key
.map(value => [value, this.throughputChartData[value].count]);
return [
{
name: THROUGHPUT_STRINGS.Y_AXIS_TITLE,
name: THROUGHPUT_CHART_STRINGS.Y_AXIS_TITLE,
data,
},
];
},
chartDataLoading() {
return this.$apollo.queries.throughputChartData.loading;
return !this.hasError && this.$apollo.queries.throughputChartData.loading;
},
chartDataAvailable() {
return this.formattedThroughputChartData[0].data.length;
return this.formattedThroughputChartData[0]?.data.length;
},
alertDetails() {
return {
class: this.hasError ? 'danger' : 'info',
message: this.hasError
? THROUGHPUT_CHART_STRINGS.ERROR_FETCHING_DATA
: THROUGHPUT_CHART_STRINGS.NO_DATA,
};
},
},
strings: {
chartTitle: THROUGHPUT_STRINGS.CHART_TITLE,
chartDescription: THROUGHPUT_STRINGS.CHART_DESCRIPTION,
noData: THROUGHPUT_STRINGS.NO_DATA,
chartTitle: THROUGHPUT_CHART_STRINGS.CHART_TITLE,
chartDescription: THROUGHPUT_CHART_STRINGS.CHART_DESCRIPTION,
},
};
</script>
......@@ -87,6 +100,8 @@ export default {
:data="formattedThroughputChartData"
:option="chartOptions"
/>
<gl-alert v-else :dismissible="false" class="gl-mt-4">{{ $options.strings.noData }}</gl-alert>
<gl-alert v-else :variant="alertDetails.class" :dismissible="false" class="gl-mt-4">{{
alertDetails.message
}}</gl-alert>
</div>
</template>
import { __ } from '~/locale';
export const DEFAULT_NUMBER_OF_DAYS = 365;
export const THROUGHPUT_STRINGS = {
export const THROUGHPUT_CHART_STRINGS = {
CHART_TITLE: __('Throughput'),
Y_AXIS_TITLE: __('Merge Requests merged'),
X_AXIS_TITLE: __('Month'),
CHART_DESCRIPTION: __('The number of merge requests merged by month.'),
NO_DATA: __('There is no data available.'),
NO_DATA: __('There is no chart data available.'),
ERROR_FETCHING_DATA: __('There was an error while fetching the chart data.'),
};
......@@ -2,7 +2,7 @@ import { shallowMount } from '@vue/test-utils';
import { GlAlert, GlLoadingIcon } from '@gitlab/ui';
import { GlAreaChart } from '@gitlab/ui/dist/charts';
import ThroughputChart from 'ee/analytics/merge_request_analytics/components/throughput_chart.vue';
import { THROUGHPUT_STRINGS } from 'ee/analytics/merge_request_analytics/constants';
import { THROUGHPUT_CHART_STRINGS } from 'ee/analytics/merge_request_analytics/constants';
import { throughputChartData } from '../mock_data';
const fullPath = 'gitlab-org/gitlab';
......@@ -48,20 +48,20 @@ describe('ThroughputChart', () => {
it('displays the chart title', () => {
const chartTitle = wrapper.find('[data-testid="chartTitle"').text();
expect(chartTitle).toBe(THROUGHPUT_STRINGS.CHART_TITLE);
expect(chartTitle).toBe(THROUGHPUT_CHART_STRINGS.CHART_TITLE);
});
it('displays the chart description', () => {
const chartDescription = wrapper.find('[data-testid="chartDescription"').text();
expect(chartDescription).toBe(THROUGHPUT_STRINGS.CHART_DESCRIPTION);
expect(chartDescription).toBe(THROUGHPUT_CHART_STRINGS.CHART_DESCRIPTION);
});
it('displays an empty state message when there is no data', () => {
const alert = wrapper.find(GlAlert);
expect(alert.exists()).toBe(true);
expect(alert.text()).toBe(THROUGHPUT_STRINGS.NO_DATA);
expect(alert.text()).toBe(THROUGHPUT_CHART_STRINGS.NO_DATA);
});
it('does not display a loading icon', () => {
......@@ -86,7 +86,7 @@ describe('ThroughputChart', () => {
displaysComponent(GlAreaChart, false);
});
it('does not display the no data message', () => {
it('does not display a no data message', () => {
displaysComponent(GlAlert, false);
});
});
......@@ -104,8 +104,29 @@ describe('ThroughputChart', () => {
displaysComponent(GlLoadingIcon, false);
});
it('does not display the no data message', () => {
it('does not display a no data message', () => {
displaysComponent(GlAlert, false);
});
});
describe('with errors', () => {
beforeEach(() => {
createComponent({ data: { hasError: true } });
});
it('does not display the chart', () => {
displaysComponent(GlAreaChart, false);
});
it('does not display a loading icon', () => {
displaysComponent(GlLoadingIcon, false);
});
it('displays an error message', () => {
const alert = wrapper.find(GlAlert);
expect(alert.exists()).toBe(true);
expect(alert.text()).toBe(THROUGHPUT_CHART_STRINGS.ERROR_FETCHING_DATA);
});
});
});
......@@ -24443,7 +24443,7 @@ msgstr ""
msgid "There is already a repository with that name on disk"
msgstr ""
msgid "There is no data available."
msgid "There is no chart data available."
msgstr ""
msgid "There is no data available. Please change your selection."
......@@ -24611,6 +24611,9 @@ msgstr ""
msgid "There was an error when unsubscribing from this label."
msgstr ""
msgid "There was an error while fetching the chart data."
msgstr ""
msgid "There was an error while fetching value stream analytics data."
msgstr ""
......
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