Commit 78d2f78e authored by Scott Hampton's avatar Scott Hampton

Add chart empty state

Add an empty state for when there is no coverage
data.

Add clarifying wording to changelog.

Update gitlab.pot.
parent 66a34007
<script> <script>
import chartEmptyStateIllustration from '@gitlab/svgs/dist/illustrations/chart-empty-state.svg';
import { GlAreaChart } from '@gitlab/ui/dist/charts'; import { GlAreaChart } from '@gitlab/ui/dist/charts';
import { GlCard, GlSprintf } from '@gitlab/ui'; import { GlCard, GlSprintf, GlSafeHtmlDirective as SafeHtml } from '@gitlab/ui';
import { __, s__ } from '~/locale'; import { __, s__ } from '~/locale';
import MetricCard from '~/analytics/shared/components/metric_card.vue'; import MetricCard from '~/analytics/shared/components/metric_card.vue';
import { formatDate } from '~/lib/utils/datetime_utility'; import { formatDate } from '~/lib/utils/datetime_utility';
...@@ -19,6 +20,9 @@ export default { ...@@ -19,6 +20,9 @@ export default {
GlSprintf, GlSprintf,
MetricCard, MetricCard,
}, },
directives: {
SafeHtml,
},
inject: { inject: {
groupFullPath: { groupFullPath: {
default: '', default: '',
...@@ -75,6 +79,9 @@ export default { ...@@ -75,6 +79,9 @@ export default {
}; };
}, },
computed: { computed: {
isChartEmpty() {
return !this.groupCoverageChartData?.[0]?.data?.length;
},
metrics() { metrics() {
return [ return [
{ {
...@@ -130,18 +137,20 @@ export default { ...@@ -130,18 +137,20 @@ export default {
}, },
}, },
i18n: { i18n: {
emptyChart: s__('RepositoriesAnalytics|No test coverage to display'),
graphCardHeader: s__('RepositoriesAnalytics|Average test coverage last 30 days'), graphCardHeader: s__('RepositoriesAnalytics|Average test coverage last 30 days'),
yAxisName: __('Coverage'), yAxisName: __('Coverage'),
xAxisName: __('Date'), xAxisName: __('Date'),
graphName: s__('RepositoriesAnalytics|Average coverage'), graphName: s__('RepositoriesAnalytics|Average coverage'),
graphTooltipMessage: __('Code Coverage: %{coveragePercentage}'), graphTooltipMessage: __('Code Coverage: %{coveragePercentage}'),
metrics: { metrics: {
cardTitle: __('Overall activity'), cardTitle: s__('RepositoriesAnalytics|Overall activity'),
projectCountLabel: s__('RepositoriesAnalytics|Projects with Coverage'), projectCountLabel: s__('RepositoriesAnalytics|Projects with Coverage'),
averageCoverageLabel: s__('RepositoriesAnalytics|Average Coverage by Job'), averageCoverageLabel: s__('RepositoriesAnalytics|Average Coverage by Job'),
coverageCountLabel: s__('RepositoriesAnalytics|Jobs with Coverage'), coverageCountLabel: s__('RepositoriesAnalytics|Jobs with Coverage'),
}, },
}, },
chartEmptyStateIllustration,
}; };
</script> </script>
<template> <template>
...@@ -159,6 +168,19 @@ export default { ...@@ -159,6 +168,19 @@ export default {
<chart-skeleton-loader v-if="isLoading" data-testid="group-coverage-chart-loading" /> <chart-skeleton-loader v-if="isLoading" data-testid="group-coverage-chart-loading" />
<div
v-else-if="isChartEmpty"
class="d-flex flex-column justify-content-center gl-my-7"
data-testid="group-coverage-chart-empty"
>
<div
v-safe-html="$options.chartEmptyStateIllustration"
class="gl-my-5 svg-w-100 d-flex align-items-center"
data-testid="chart-empty-state-illustration"
></div>
<h5 class="text-center">{{ $options.i18n.emptyChart }}</h5>
</div>
<gl-area-chart <gl-area-chart
v-else v-else
:data="groupCoverageChartData" :data="groupCoverageChartData"
......
--- ---
title: Adds a graph to the group repositories analytics page title: Adds a historical coverage graph to the group repositories analytics page
merge_request: 53319 merge_request: 53319
author: author:
type: added type: added
...@@ -14,6 +14,7 @@ describe('Test coverage table component', () => { ...@@ -14,6 +14,7 @@ describe('Test coverage table component', () => {
const findTotalCoverages = () => wrapper.find('.js-metric-card-item:nth-child(3) h3'); const findTotalCoverages = () => wrapper.find('.js-metric-card-item:nth-child(3) h3');
const findGroupCoverageChart = () => wrapper.findByTestId('group-coverage-chart'); const findGroupCoverageChart = () => wrapper.findByTestId('group-coverage-chart');
const findChartLoadingState = () => wrapper.findByTestId('group-coverage-chart-loading'); const findChartLoadingState = () => wrapper.findByTestId('group-coverage-chart-loading');
const findChartEmptyState = () => wrapper.findByTestId('group-coverage-chart-empty');
const findLoadingState = () => wrapper.find(GlSkeletonLoading); const findLoadingState = () => wrapper.find(GlSkeletonLoading);
const createComponent = ({ data = {} } = {}) => { const createComponent = ({ data = {} } = {}) => {
...@@ -59,6 +60,13 @@ describe('Test coverage table component', () => { ...@@ -59,6 +60,13 @@ describe('Test coverage table component', () => {
expect(findAverageCoverage().text()).toBe('-'); expect(findAverageCoverage().text()).toBe('-');
expect(findTotalCoverages().text()).toBe('-'); expect(findTotalCoverages().text()).toBe('-');
}); });
it('renders empty chart state', () => {
createComponent();
expect(findChartEmptyState().exists()).toBe(true);
expect(findGroupCoverageChart().exists()).toBe(false);
});
}); });
describe('when query is loading', () => { describe('when query is loading', () => {
......
...@@ -20919,9 +20919,6 @@ msgstr "" ...@@ -20919,9 +20919,6 @@ msgstr ""
msgid "Outdent" msgid "Outdent"
msgstr "" msgstr ""
msgid "Overall activity"
msgstr ""
msgid "Overridden" msgid "Overridden"
msgstr "" msgstr ""
...@@ -24852,6 +24849,12 @@ msgstr "" ...@@ -24852,6 +24849,12 @@ msgstr ""
msgid "RepositoriesAnalytics|Latest test coverage results" msgid "RepositoriesAnalytics|Latest test coverage results"
msgstr "" msgstr ""
msgid "RepositoriesAnalytics|No test coverage to display"
msgstr ""
msgid "RepositoriesAnalytics|Overall activity"
msgstr ""
msgid "RepositoriesAnalytics|Please select a project or multiple projects to display their most recent test coverage data." msgid "RepositoriesAnalytics|Please select a project or multiple projects to display their most recent test coverage data."
msgstr "" 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