Commit 3946e937 authored by Scott Hampton's avatar Scott Hampton

Graph group average code coverage

Add a graph to the group repo analytics page to
represent the average coverage of all projects
in the group over the past 30 days.
parent 2fc1ffff
......@@ -24,7 +24,7 @@ export default {
<h4 data-testid="test-coverage-header">
{{ $options.text.codeCoverageHeader }}
</h4>
<test-coverage-summary />
<test-coverage-summary class="gl-mb-5" />
<test-coverage-table class="gl-mb-5" />
<download-test-coverage />
</div>
......
<script>
import { GlAreaChart } from '@gitlab/ui/dist/charts';
import { GlCard, GlSprintf } from '@gitlab/ui';
import { __, s__ } from '~/locale';
import MetricCard from '~/analytics/shared/components/metric_card.vue';
import { formatDate } from '~/lib/utils/datetime_utility';
import ChartSkeletonLoader from '~/vue_shared/components/resizable_chart/skeleton_loader.vue';
import getGroupTestCoverage from '../graphql/queries/get_group_test_coverage.query.graphql';
export default {
name: 'TestCoverageSummary',
components: {
ChartSkeletonLoader,
GlAreaChart,
GlCard,
GlSprintf,
MetricCard,
},
inject: {
......@@ -17,26 +25,37 @@ export default {
group: {
query: getGroupTestCoverage,
variables() {
const ONE_WEEK = 7 * 24 * 60 * 60 * 1000; // milliseconds
const THIRTY_DAYS = 30 * 24 * 60 * 60 * 1000; // milliseconds
return {
groupFullPath: this.groupFullPath,
startDate: new Date(Date.now() - ONE_WEEK),
startDate: new Date(Date.now() - THIRTY_DAYS),
};
},
result(res) {
const groupCoverage = res.data?.group?.codeCoverageActivities?.nodes;
const { projectCount, averageCoverage, coverageCount } =
res.data?.group?.codeCoverageActivities?.nodes?.[0] || {};
groupCoverage?.[groupCoverage.length - 1] || {};
this.projectCount = projectCount;
this.averageCoverage = averageCoverage;
this.coverageCount = coverageCount;
this.groupCoverageChartData = [
{
name: this.$options.text.graphName,
data: groupCoverage.map((coverage) => [
formatDate(coverage.date, 'mmm dd'),
coverage.averageCoverage,
]),
},
];
},
error() {
this.hasError = true;
this.projectCount = null;
this.averageCoverage = null;
this.coverageCount = null;
this.groupCoverageChartData = [];
},
watchLoading(isLoading) {
this.isLoading = isLoading;
......@@ -48,6 +67,9 @@ export default {
projectCount: null,
averageCoverage: null,
coverageCount: null,
groupCoverageChartData: [],
coveragePercentage: null,
tooltipTitle: null,
hasError: false,
isLoading: false,
};
......@@ -76,9 +98,68 @@ export default {
},
];
},
chartOptions() {
return {
xAxis: {
name: this.$options.text.xAxisName,
type: 'category',
},
yAxis: {
name: this.$options.text.yAxisName,
type: 'value',
min: 0,
max: 100,
axisLabel: {
formatter: (value) => `${value}%`,
},
},
};
},
},
methods: {
formatTooltipText(params) {
this.tooltipTitle = params.value;
this.coveragePercentage = params.seriesData?.[0]?.data?.[1];
},
},
text: {
graphCardHeader: s__('RepositoriesAnalytics|Average test coverage last 30 days'),
yAxisName: __('Coverage'),
xAxisName: __('Date'),
graphName: s__('RepositoriesAnalytics|Average coverage'),
},
};
</script>
<template>
<metric-card :title="$options.i18n.cardTitle" :metrics="metrics" :is-loading="isLoading" />
<div>
<metric-card :title="$options.i18n.cardTitle" :metrics="metrics" :is-loading="isLoading" />
<gl-card>
<template #header>
<h5>{{ $options.text.graphCardHeader }}</h5>
</template>
<chart-skeleton-loader v-if="isLoading" />
<gl-area-chart
v-else
:data="groupCoverageChartData"
:option="chartOptions"
:include-legend-avg-max="false"
:format-tooltip-text="formatTooltipText"
>
<template #tooltip-title>
{{ tooltipTitle }}
</template>
<template #tooltip-content>
<gl-sprintf :message="__('Code Coverage: %{coveragePercentage}%{percentSymbol}')">
<template #coveragePercentage>
{{ coveragePercentage }}
</template>
<template #percentSymbol>%</template>
</gl-sprintf>
</template>
</gl-area-chart>
</gl-card>
</div>
</template>
query getGroupTestCoverage($groupFullPath: ID!, $startDate: Date!, $last: Int = 1) {
query getGroupTestCoverage($groupFullPath: ID!, $startDate: Date!) {
group(fullPath: $groupFullPath) {
codeCoverageActivities(startDate: $startDate, last: $last) {
fullPath
codeCoverageActivities(startDate: $startDate) {
nodes {
projectCount
averageCoverage
......
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