Skip to content

Add MilestoneLink DataTable cell component and use for MR analytics dashboard

Everyone can contribute. Help move this issue forward while earning points, leveling up and collecting rewards.

Problem

The default formatting applied to DataTable cells is converting milestones (17.5, 18.6, etc) to integers (17, 18, etc).

Solution

Create a new MilestoneLink table cell component which takes the milestone and outputs a link to the milestone. Sample diff:

diff --git a/ee/app/assets/javascripts/analytics/analytics_dashboards/components/visualizations/data_table/data_table.vue b/ee/app/assets/javascripts/analytics/analytics_dashboards/components/visualizations/data_table/data_table.vue
index 51cd7face90a..612384a0eab7 100644
--- a/ee/app/assets/javascripts/analytics/analytics_dashboards/components/visualizations/data_table/data_table.vue
+++ b/ee/app/assets/javascripts/analytics/analytics_dashboards/components/visualizations/data_table/data_table.vue
@@ -20,6 +20,7 @@ export default {
     FormatTime: () => import('./format_time.vue'),
     FormatTimeRange: () => import('./format_time_range.vue'),
     MergeRequestLink: () => import('./merge_request_link.vue'),
+    MilestoneLink: () => import('./milestone_link.vue'),
     ChangePercentageIndicator: () => import('./change_percentage_indicator.vue'),
     MetricLabel: () => import('./metric_label.vue'),
     TrendLine: () => import('./trend_line.vue'),
diff --git a/ee/app/assets/javascripts/analytics/analytics_dashboards/components/visualizations/data_table/milestone_link.vue b/ee/app/assets/javascripts/analytics/analytics_dashboards/components/visualizations/data_table/milestone_link.vue
new file mode 100644
index 000000000000..8ac7ff054be6
--- /dev/null
+++ b/ee/app/assets/javascripts/analytics/analytics_dashboards/components/visualizations/data_table/milestone_link.vue
@@ -0,0 +1,23 @@
+<script>
+import { GlLink } from '@gitlab/ui';
+
+export default {
+  name: 'MilestoneLink',
+  components: {
+    GlLink,
+  },
+  props: {
+    title: {
+      type: String,
+      required: true,
+    },
+    webPath: {
+      type: String,
+      required: true,
+    },
+  },
+};
+</script>
+<template>
+  <gl-link :href="webPath" target="_blank">{{ title }}</gl-link>
+</template>
diff --git a/ee/app/assets/javascripts/analytics/analytics_dashboards/data_sources/merge_requests.js b/ee/app/assets/javascripts/analytics/analytics_dashboards/data_sources/merge_requests.js
index efbea2e1bf40..e93c4c4da2e0 100644
--- a/ee/app/assets/javascripts/analytics/analytics_dashboards/data_sources/merge_requests.js
+++ b/ee/app/assets/javascripts/analytics/analytics_dashboards/data_sources/merge_requests.js
@@ -49,7 +49,7 @@ const formatNodes = (list) => {
         },
         diffStatsSummary,
         pipelinesCount,
-        milestone: milestone?.title,
+        milestone,
       };
     },
   );
diff --git a/ee/app/assets/javascripts/analytics/merge_request_analytics/components/stories_constants.js b/ee/app/assets/javascripts/analytics/merge_request_analytics/components/stories_constants.js
index 2012ae66c99f..1ad11e3eadbe 100644
--- a/ee/app/assets/javascripts/analytics/merge_request_analytics/components/stories_constants.js
+++ b/ee/app/assets/javascripts/analytics/merge_request_analytics/components/stories_constants.js
@@ -38,7 +38,7 @@ export const throughputTableData = {
           createdAt: '2020-08-06T16:53:50Z',
           mergedAt: '2020-08-06T16:57:53Z',
           webUrl: 'http://127.0.0.1:3001/gitlab-org/gitlab-shell/-/merge_requests/11',
-          milestone: null,
+          milestone: { title: '18.0' },
           assignees: {
             nodes: [
               {
@@ -70,7 +70,7 @@ export const throughputTableData = {
           createdAt: '2020-08-06T16:53:50Z',
           mergedAt: '2020-08-06T16:57:53Z',
           webUrl: 'http://127.0.0.1:3001/gitlab-org/gitlab-shell/-/merge_requests/11',
-          milestone: null,
+          milestone: { title: 'Milestone string title' },
           assignees: {
             nodes: [
               {
diff --git a/ee/app/assets/javascripts/analytics/merge_request_analytics/graphql/queries/throughput_table.query.graphql b/ee/app/assets/javascripts/analytics/merge_request_analytics/graphql/queries/throughput_table.query.graphql
index df69dce3e906..c91921775da5 100644
--- a/ee/app/assets/javascripts/analytics/merge_request_analytics/graphql/queries/throughput_table.query.graphql
+++ b/ee/app/assets/javascripts/analytics/merge_request_analytics/graphql/queries/throughput_table.query.graphql
@@ -48,6 +48,7 @@ query getThroughputTableData(
         milestone {
           id
           title
+          webPath
         }
         assignees {
           nodes {
diff --git a/ee/app/validators/json_schemas/analytics_visualization.json b/ee/app/validators/json_schemas/analytics_visualization.json
index 3f174f52c6a4..8bbbe30124c5 100644
--- a/ee/app/validators/json_schemas/analytics_visualization.json
+++ b/ee/app/validators/json_schemas/analytics_visualization.json
@@ -153,6 +153,7 @@
                   "FormatTime",
                   "FormatTimeRange",
                   "MergeRequestLink",
+                  "MilestoneLink",
                   "ChangePercentageIndicator",
                   "MetricLabel",
                   "TrendLine"
diff --git a/ee/lib/gitlab/analytics/merge_requests/visualizations/merge_requests_throughput_table.yaml b/ee/lib/gitlab/analytics/merge_requests/visualizations/merge_requests_throughput_table.yaml
index 51556d095def..5065cb42a9cb 100644
--- a/ee/lib/gitlab/analytics/merge_requests/visualizations/merge_requests_throughput_table.yaml
+++ b/ee/lib/gitlab/analytics/merge_requests/visualizations/merge_requests_throughput_table.yaml
@@ -23,6 +23,7 @@ options:
       component: FormatTimeRange
     - key: milestone
       label: Milestone
+      component: MilestoneLink
     - key: commitCount
       label: Commits
     - key: pipelinesCount

Testing

To avoid future regressions, we should also expand the MR analytics feature test suite to validate that the milestone is rendering correctly (thread)

Background

Thread where issue was first mentioned: https://gitlab.slack.com/archives/CJZR6KPB4/p1761154465019079

Edited by Alex Pennells