diff --git a/ee/app/assets/javascripts/vue_shared/components/customizable_dashboard/panels_base.vue b/ee/app/assets/javascripts/vue_shared/components/customizable_dashboard/panels_base.vue index 81d22d9508bd06adb7e1b6d1d4e536da3c45ced6..dbbd7cf8f2d0cd7963915084b93b36fbfc13983c 100644 --- a/ee/app/assets/javascripts/vue_shared/components/customizable_dashboard/panels_base.vue +++ b/ee/app/assets/javascripts/vue_shared/components/customizable_dashboard/panels_base.vue @@ -145,7 +145,13 @@ export default { return this.namespaceFullPath; }, panelTitle() { - return sprintf(this.title, { namespaceName: this.rootNamespaceName }); + return sprintf(this.title, { + namespaceName: this.namespaceName, + namespaceType: this.isProject ? __('project') : __('group'), + namespaceFullPath: this.namespaceFullPath, + rootNamespaceName: this.rootNamespaceName, + rootNamespaceFullPath: this.rootNamespaceFullPath, + }); }, }, watch: { diff --git a/ee/lib/gitlab/analytics/ai_impact_dashboard/dashboard.yaml b/ee/lib/gitlab/analytics/ai_impact_dashboard/dashboard.yaml index e1832dbb1ba1bba697ddee1431754c3f378836a4..8f02a05c7b8939ab0438c13ac641eabcccaca0ae 100644 --- a/ee/lib/gitlab/analytics/ai_impact_dashboard/dashboard.yaml +++ b/ee/lib/gitlab/analytics/ai_impact_dashboard/dashboard.yaml @@ -2,7 +2,7 @@ title: AI impact analytics description: Visualize the relation between AI usage and SDLC trends. panels: - - title: 'Metric trends for group: %{namespaceName}' + - title: 'Metric trends for %{namespaceType}: %{namespaceName}' visualization: ai_impact_table gridAttributes: yPos: 0 diff --git a/ee/lib/gitlab/analytics/value_stream_dashboard/dashboards/value_streams_dashboard.yaml b/ee/lib/gitlab/analytics/value_stream_dashboard/dashboards/value_streams_dashboard.yaml index bbb4e4749f90efe50580e0a80cf26962c03774a4..e577a22a7de37c999eaa8d007c8ee8a1f9673fe0 100644 --- a/ee/lib/gitlab/analytics/value_stream_dashboard/dashboards/value_streams_dashboard.yaml +++ b/ee/lib/gitlab/analytics/value_stream_dashboard/dashboards/value_streams_dashboard.yaml @@ -4,7 +4,7 @@ description: The Value Streams Dashboard allows all stakeholders from executives panels: - id: 1 visualization: dora_chart - title: Metrics comparison for %{namespaceName} group + title: Metrics comparison for %{namespaceName} %{namespaceType} gridAttributes: yPos: 1 xPos: 0 @@ -13,7 +13,7 @@ panels: options: {} - id: 2 visualization: usage_overview - title: Usage overview for %{namespaceName} group + title: Usage overview for %{rootNamespaceName} group gridAttributes: yPos: 0 xPos: 0 @@ -22,7 +22,7 @@ panels: options: {} - id: 3 visualization: dora_performers_score - title: DORA performers score for %{namespaceName} group + title: DORA performers score for %{namespaceName} %{namespaceType} gridAttributes: yPos: 7 xPos: 0 diff --git a/ee/spec/features/groups/analytics/visualizations_spec.rb b/ee/spec/features/groups/analytics/visualizations_spec.rb index f2e2a83d86cb53fa2d135ff54c5dd19f87132f07..ad73960daeb26c57b1dba2a427212d17a805e4d9 100644 --- a/ee/spec/features/groups/analytics/visualizations_spec.rb +++ b/ee/spec/features/groups/analytics/visualizations_spec.rb @@ -33,7 +33,7 @@ end it_behaves_like 'renders metrics comparison table' do - let(:group_name) { group.name } + let(:panel_title) { "#{group.name} group" } end it_behaves_like 'renders contributor count' @@ -47,7 +47,7 @@ end it_behaves_like 'renders metrics comparison table' do - let(:group_name) { group.name } + let(:panel_title) { "#{group.name} group" } end it_behaves_like 'does not render contributor count' @@ -99,7 +99,7 @@ end it_behaves_like 'renders metrics comparison table' do - let(:group_name) { group.name } + let(:panel_title) { "#{group.name} group" } end it_behaves_like 'renders contributor count' diff --git a/ee/spec/features/projects/analytics/dashboards_spec.rb b/ee/spec/features/projects/analytics/dashboards_spec.rb index 36dcca3930c55342d99ed44e88c5190a639308d0..17eabade8d8622f372c8a9ec2b2f5efb61b03191 100644 --- a/ee/spec/features/projects/analytics/dashboards_spec.rb +++ b/ee/spec/features/projects/analytics/dashboards_spec.rb @@ -88,7 +88,7 @@ it_behaves_like 'renders usage overview metrics' it_behaves_like 'renders metrics comparison table' do - let(:group_name) { group.name } + let(:panel_title) { "#{project.name} project" } end it 'renders the dora performers score with an error' do @@ -96,7 +96,7 @@ 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} group"), name: group.name) + 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.") end diff --git a/ee/spec/frontend/vue_shared/components/customizable_dashboard/panels_base_spec.js b/ee/spec/frontend/vue_shared/components/customizable_dashboard/panels_base_spec.js index 42dce6d740127da971f70a35b5992f4ea54d52d6..35946b1063b42f09b963824bda289df07e453f1c 100644 --- a/ee/spec/frontend/vue_shared/components/customizable_dashboard/panels_base_spec.js +++ b/ee/spec/frontend/vue_shared/components/customizable_dashboard/panels_base_spec.js @@ -28,7 +28,7 @@ describe('PanelsBase', () => { /** @type {import('helpers/vue_test_utils_helper').ExtendedWrapper} */ let wrapper; - const createWrapper = (props = {}, mountFn = shallowMountExtended) => { + const createWrapper = ({ props = {}, provide = {}, mountFn = shallowMountExtended } = {}) => { wrapper = mountFn(PanelsBase, { provide: { namespaceId: '1', @@ -37,6 +37,7 @@ describe('PanelsBase', () => { rootNamespaceName: 'MEOW', rootNamespaceFullPath: 'namespace', isProject: true, + ...provide, }, propsData: { title: panelConfig.title, @@ -87,7 +88,7 @@ describe('PanelsBase', () => { describe('when a visualization does not match the analytics schema', () => { beforeEach(() => { createWrapper({ - visualization: invalidVisualization, + props: { visualization: invalidVisualization }, }); }); @@ -324,7 +325,7 @@ describe('PanelsBase', () => { beforeEach(() => { jest.spyOn(dataSources.cube_analytics(), 'fetch').mockReturnValue(new Promise(() => {})); - createWrapper({ filters }); + createWrapper({ props: { filters } }); return waitForPromises(); }); @@ -337,7 +338,7 @@ describe('PanelsBase', () => { describe('when the panel has no title', () => { beforeEach(() => { - createWrapper({ title: null }); + createWrapper({ props: { title: null } }); }); it('should not render the title', () => { @@ -347,7 +348,55 @@ describe('PanelsBase', () => { describe('when the title includes %{namespaceName}', () => { beforeEach(() => { - createWrapper({ title: 'title for %{namespaceName}' }); + createWrapper({ props: { title: 'title for %{namespaceName}' } }); + }); + + it('replaces the token with the namespace name', () => { + expect(findPanelTitle().text()).toBe('title for Namespace name'); + }); + }); + + describe('when the title includes %{namespaceFullPath}', () => { + beforeEach(() => { + createWrapper({ props: { title: 'title for %{namespaceFullPath}' } }); + }); + + it('replaces the token with the root namespace name', () => { + expect(findPanelTitle().text()).toBe('title for namespace/full/path'); + }); + }); + + describe('when the title includes %{namespaceType}', () => { + describe('for group', () => { + beforeEach(() => { + createWrapper({ + props: { title: 'title for %{namespaceType}' }, + provide: { isProject: false }, + }); + }); + + it('replaces the token with `group`', () => { + expect(findPanelTitle().text()).toBe('title for group'); + }); + }); + + describe('for project', () => { + beforeEach(() => { + createWrapper({ + props: { title: 'title for %{namespaceType}' }, + provide: { isProject: true }, + }); + }); + + it('replaces the token with `project`', () => { + expect(findPanelTitle().text()).toBe('title for project'); + }); + }); + }); + + describe('when the title includes %{rootNamespaceName}', () => { + beforeEach(() => { + createWrapper({ props: { title: 'title for %{rootNamespaceName}' } }); }); it('replaces the token with the root namespace name', () => { @@ -355,9 +404,19 @@ describe('PanelsBase', () => { }); }); + describe('when the title includes %{rootNamespaceFullPath}', () => { + beforeEach(() => { + createWrapper({ props: { title: 'title for %{rootNamespaceFullPath}' } }); + }); + + it('replaces the token with the root namespace name', () => { + expect(findPanelTitle().text()).toBe('title for namespace'); + }); + }); + describe('when editing', () => { beforeEach(() => { - createWrapper({ editing: true }, mountExtended); + createWrapper({ props: { editing: true }, mountFn: mountExtended }); }); it('should render actions dropdown', () => { @@ -374,7 +433,10 @@ describe('PanelsBase', () => { describe('when editing with a visualization error', () => { beforeEach(() => { - createWrapper({ editing: true, visualization: invalidVisualization }, mountExtended); + createWrapper({ + props: { editing: true, visualization: invalidVisualization }, + mountFn: mountExtended, + }); }); it('shows the error popover when the dropdown is closed', () => { diff --git a/spec/support/shared_examples/features/value_streams_dashboard_shared_examples.rb b/spec/support/shared_examples/features/value_streams_dashboard_shared_examples.rb index f29b9409fdf9ec5b76df1f68400147e2127d8572..fff8569b31f2e5f54699e8f48f543c88e6af7245 100644 --- a/spec/support/shared_examples/features/value_streams_dashboard_shared_examples.rb +++ b/spec/support/shared_examples/features/value_streams_dashboard_shared_examples.rb @@ -40,7 +40,7 @@ it 'renders the metrics comparison visualization' do expect(metric_table).to be_visible - expect(metric_table).to have_content format(_("Metrics comparison for %{name} group"), name: group_name) + expect(metric_table).to have_content format(_("Metrics comparison for %{title}"), title: panel_title) end it "renders the available metrics" do