From 027089c345dde71056fe56af97f39de8a89d4edf Mon Sep 17 00:00:00 2001
From: Rudy Crespo <rcrespo@gitlab.com>
Date: Mon, 3 Jun 2024 16:37:54 +0000
Subject: [PATCH] Remove DORA Performers Score panel from built-in project VSD

To remove the DORA Performers Score panel from the built-in Value
Streams Dashboard at the project level, we return a separate YAML file
without it.

Changelog: changed
EE: true
---
 doc/user/analytics/value_streams_dashboard.md |  2 +-
 ee/app/models/product_analytics/dashboard.rb  |  9 ++--
 .../project_value_streams_dashboard.yaml      | 20 +++++++
 .../projects/analytics/dashboards_spec.rb     |  9 +---
 .../product_analytics/dashboard_spec.rb       | 52 ++++++++++++++-----
 5 files changed, 68 insertions(+), 24 deletions(-)
 create mode 100644 ee/lib/gitlab/analytics/value_stream_dashboard/dashboards/project_value_streams_dashboard.yaml

diff --git a/doc/user/analytics/value_streams_dashboard.md b/doc/user/analytics/value_streams_dashboard.md
index ebd9620f72c12..81d47e1098691 100644
--- a/doc/user/analytics/value_streams_dashboard.md
+++ b/doc/user/analytics/value_streams_dashboard.md
@@ -116,7 +116,7 @@ panels:
 > - [Enabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/439737) in GitLab 16.9.
 > - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/440694) in GitLab 16.11. Feature flag `dora_performers_score_panel` removed.
 
-The [DORA metrics](dora_metrics.md) Performers score panel is a bar chart that visualizes the status of the organization's DevOps performance levels across different projects.
+The [DORA metrics](dora_metrics.md) Performers score panel is a group-level bar chart that visualizes the status of the organization's DevOps performance levels across different projects.
 
 The chart is a breakdown of your project's DORA scores, [categorized](https://cloud.google.com/blog/products/devops-sre/dora-2022-accelerate-state-of-devops-report-now-out) as high, medium, or low.
 The chart aggregates all the child projects in the group.
diff --git a/ee/app/models/product_analytics/dashboard.rb b/ee/app/models/product_analytics/dashboard.rb
index f543e58ba863d..31d33be7ce9de 100644
--- a/ee/app/models/product_analytics/dashboard.rb
+++ b/ee/app/models/product_analytics/dashboard.rb
@@ -10,7 +10,8 @@ class Dashboard
     DASHBOARD_ROOT_LOCATION = '.gitlab/analytics/dashboards'
 
     PRODUCT_ANALYTICS_DASHBOARDS_LIST = %w[audience behavior].freeze
-    VALUE_STREAM_DASHBOARD_NAME = 'value_streams_dashboard'
+    VALUE_STREAMS_DASHBOARD_NAME = 'value_streams_dashboard'
+    PROJECT_VALUE_STREAMS_DASHBOARD_NAME = 'project_value_streams_dashboard'
     SCHEMA_PATH = 'ee/app/validators/json_schemas/analytics_dashboard.json'
 
     def self.for(container:, user:)
@@ -106,14 +107,16 @@ def self.product_analytics_dashboards(container, config_project, user)
     def self.value_stream_dashboard(container, config_project)
       return unless container.value_streams_dashboard_available?
 
+      config_file_name = container.is_a?(Group) ? VALUE_STREAMS_DASHBOARD_NAME : PROJECT_VALUE_STREAMS_DASHBOARD_NAME
+
       config =
         load_yaml_dashboard_config(
-          VALUE_STREAM_DASHBOARD_NAME,
+          config_file_name,
           'ee/lib/gitlab/analytics/value_stream_dashboard/dashboards'
         )
 
       new(
-        slug: VALUE_STREAM_DASHBOARD_NAME,
+        slug: VALUE_STREAMS_DASHBOARD_NAME,
         container: container,
         config: config,
         config_project: config_project,
diff --git a/ee/lib/gitlab/analytics/value_stream_dashboard/dashboards/project_value_streams_dashboard.yaml b/ee/lib/gitlab/analytics/value_stream_dashboard/dashboards/project_value_streams_dashboard.yaml
new file mode 100644
index 0000000000000..79ae809dc589d
--- /dev/null
+++ b/ee/lib/gitlab/analytics/value_stream_dashboard/dashboards/project_value_streams_dashboard.yaml
@@ -0,0 +1,20 @@
+---
+title: Value Streams Dashboard
+description: Track key DevSecOps metrics throughout the development lifecycle.
+panels:
+  - visualization: dora_chart
+    title: Metrics comparison for %{namespaceName} %{namespaceType}
+    gridAttributes:
+      yPos: 1
+      xPos: 0
+      width: 12
+      height: 6
+    options: {}
+  - visualization: usage_overview
+    title: Usage overview for %{namespaceName} %{namespaceType}
+    gridAttributes:
+      yPos: 0
+      xPos: 0
+      width: 12
+      height: 1
+    options: {}
diff --git a/ee/spec/features/projects/analytics/dashboards_spec.rb b/ee/spec/features/projects/analytics/dashboards_spec.rb
index 7dd622f9ed8c7..569e97b2fd02f 100644
--- a/ee/spec/features/projects/analytics/dashboards_spec.rb
+++ b/ee/spec/features/projects/analytics/dashboards_spec.rb
@@ -94,14 +94,9 @@
           let(:panel_title) { "#{project.name} project" }
         end
 
-        it 'renders the dora performers score with an error' do
+        it 'does not render dora performers score panel' do
           # Currently not supported at the project level
-          dora_performers_score = find_by_testid('panel-dora-performers-score')
-          expect(dora_performers_score).to be_visible
-
-          panel_title = format(_("DORA performers score for %{name} project"), name: project.name)
-          expect(dora_performers_score).to have_content panel_title
-          expect(dora_performers_score).to have_content _("Something went wrong.")
+          expect(page).not_to have_selector("[data-testid='panel-dora-performers-score']")
         end
 
         it_behaves_like 'does not render contributor count'
diff --git a/ee/spec/models/product_analytics/dashboard_spec.rb b/ee/spec/models/product_analytics/dashboard_spec.rb
index 5f1a15b434584..3f55bc60a936a 100644
--- a/ee/spec/models/product_analytics/dashboard_spec.rb
+++ b/ee/spec/models/product_analytics/dashboard_spec.rb
@@ -23,6 +23,16 @@
     )
   end
 
+  shared_examples 'returns the value streams dashboard' do
+    it 'returns the value streams dashboard' do
+      expect(dashboard).to be_a(described_class)
+      expect(dashboard.title).to eq('Value Streams Dashboard')
+      expect(dashboard.slug).to eq('value_streams_dashboard')
+      expect(dashboard.description).to eq('Track key DevSecOps metrics throughout the development lifecycle.')
+      expect(dashboard.schema_version).to eq(nil)
+    end
+  end
+
   describe '#errors' do
     let(:dashboard) do
       described_class.new(
@@ -245,15 +255,28 @@
   end
 
   describe '.value_stream_dashboard' do
-    subject { described_class.value_stream_dashboard(project, config_project) }
+    context 'for groups' do
+      let(:dashboard) { described_class.value_stream_dashboard(group, config_project) }
 
-    it 'returns the value stream dashboard' do
-      dashboard = subject
-      expect(dashboard).to be_a(described_class)
-      expect(dashboard.title).to eq('Value Streams Dashboard')
-      expect(dashboard.slug).to eq('value_streams_dashboard')
-      expect(dashboard.description).to eq('Track key DevSecOps metrics throughout the development lifecycle.')
-      expect(dashboard.schema_version).to eq(nil)
+      it_behaves_like 'returns the value streams dashboard'
+
+      it 'returns the correct panels' do
+        expect(dashboard.panels.size).to eq(3)
+        expect(dashboard.panels.map { |panel| panel.visualization.type }).to eq(
+          %w[DORAChart UsageOverview DoraPerformersScore]
+        )
+      end
+    end
+
+    context 'for projects' do
+      let(:dashboard) { described_class.value_stream_dashboard(project, config_project) }
+
+      it_behaves_like 'returns the value streams dashboard'
+
+      it 'returns the correct panels' do
+        expect(dashboard.panels.size).to eq(2)
+        expect(dashboard.panels.map { |panel| panel.visualization.type }).to eq(%w[DORAChart UsageOverview])
+      end
     end
 
     context 'with the project_analytics_dashboard_dynamic_vsd feature flag disabled' do
@@ -270,12 +293,15 @@
       end
 
       context 'for groups' do
-        it 'returns the value streams dashboard' do
-          dashboard = described_class.value_stream_dashboard(group, config_project)
+        let(:dashboard) { described_class.value_stream_dashboard(group, config_project) }
+
+        it_behaves_like 'returns the value streams dashboard'
 
-          expect(dashboard).to be_a(described_class)
-          expect(dashboard.title).to eq('Value Streams Dashboard')
-          expect(dashboard.slug).to eq('value_streams_dashboard')
+        it 'returns the correct panels' do
+          expect(dashboard.panels.size).to eq(3)
+          expect(dashboard.panels.map { |panel| panel.visualization.type }).to eq(
+            %w[DORAChart UsageOverview DoraPerformersScore]
+          )
         end
       end
     end
-- 
GitLab