Commit 95aa9820 authored by Michael Kozono's avatar Michael Kozono

Merge branch '38319-rename-cycle-analytics-to-value-stream-analytics' into 'master'

Rename Cycle Analytics façades to Value Stream Analytics

Closes #38319

See merge request gitlab-org/gitlab!23427
parents a411d98a a1cf08b7
...@@ -27,7 +27,7 @@ export default { ...@@ -27,7 +27,7 @@ export default {
<template> <template>
<div class="landing content-block"> <div class="landing content-block">
<button <button
:aria-label="__('Dismiss Cycle Analytics introduction box')" :aria-label="__('Dismiss Value Stream Analytics introduction box')"
class="js-ca-dismiss-button dismiss-button" class="js-ca-dismiss-button dismiss-button"
type="button" type="button"
@click="dismissOverviewDialog" @click="dismissOverviewDialog"
...@@ -36,10 +36,10 @@ export default { ...@@ -36,10 +36,10 @@ export default {
</button> </button>
<div class="svg-container" v-html="iconCycleAnalyticsSplash"></div> <div class="svg-container" v-html="iconCycleAnalyticsSplash"></div>
<div class="inner-content"> <div class="inner-content">
<h4>{{ __('Introducing Cycle Analytics') }}</h4> <h4>{{ __('Introducing Value Stream Analytics') }}</h4>
<p> <p>
{{ {{
__(`Cycle Analytics gives an overview __(`Value Stream Analytics gives an overview
of how much time it takes to go from idea to production in your project.`) of how much time it takes to go from idea to production in your project.`)
}} }}
</p> </p>
......
...@@ -71,7 +71,7 @@ export default () => { ...@@ -71,7 +71,7 @@ export default () => {
}, },
created() { created() {
// Conditional check placed here to prevent this method from being called on the // Conditional check placed here to prevent this method from being called on the
// new Cycle Analytics page (i.e. the new page will be initialized blank and only // new Value Stream Analytics page (i.e. the new page will be initialized blank and only
// after a group is selected the cycle analyitcs data will be fetched). Once the // after a group is selected the cycle analyitcs data will be fetched). Once the
// old (current) page has been removed this entire created method as well as the // old (current) page has been removed this entire created method as well as the
// variable itself can be completely removed. // variable itself can be completely removed.
...@@ -81,7 +81,7 @@ export default () => { ...@@ -81,7 +81,7 @@ export default () => {
methods: { methods: {
handleError() { handleError() {
this.store.setErrorState(true); this.store.setErrorState(true);
return new Flash(__('There was an error while fetching cycle analytics data.')); return new Flash(__('There was an error while fetching value stream analytics data.'));
}, },
initDropdown() { initDropdown() {
const $dropdown = $('.js-ca-dropdown'); const $dropdown = $('.js-ca-dropdown');
......
...@@ -579,7 +579,7 @@ $calendar-border-color: rgba(#000, 0.1); ...@@ -579,7 +579,7 @@ $calendar-border-color: rgba(#000, 0.1);
$calendar-user-contrib-text: #959494; $calendar-user-contrib-text: #959494;
/* /*
* Cycle Analytics * Value Stream Analytics
*/ */
$cycle-analytics-box-padding: 30px; $cycle-analytics-box-padding: 30px;
$cycle-analytics-box-text-color: #8c8c8c; $cycle-analytics-box-text-color: #8c8c8c;
......
...@@ -35,7 +35,7 @@ module AnalyticsNavbarHelper ...@@ -35,7 +35,7 @@ module AnalyticsNavbarHelper
return unless project_nav_tab?(:cycle_analytics) return unless project_nav_tab?(:cycle_analytics)
navbar_sub_item( navbar_sub_item(
title: _('Cycle Analytics'), title: _('Value Stream Analytics'),
path: 'cycle_analytics#show', path: 'cycle_analytics#show',
link: project_cycle_analytics_path(project), link: project_cycle_analytics_path(project),
link_to_options: { class: 'shortcuts-project-cycle-analytics' } link_to_options: { class: 'shortcuts-project-cycle-analytics' }
......
...@@ -42,8 +42,8 @@ ...@@ -42,8 +42,8 @@
- unless should_display_analytics_pages_in_sidebar - unless should_display_analytics_pages_in_sidebar
- if can?(current_user, :read_cycle_analytics, @project) - if can?(current_user, :read_cycle_analytics, @project)
= nav_link(path: 'cycle_analytics#show') do = nav_link(path: 'cycle_analytics#show') do
= link_to project_cycle_analytics_path(@project), title: _('Cycle Analytics'), class: 'shortcuts-project-cycle-analytics' do = link_to project_cycle_analytics_path(@project), title: _('Value Stream Analytics'), class: 'shortcuts-project-cycle-analytics' do
%span= _('Cycle Analytics') %span= _('Value Stream Analytics')
= render_if_exists 'layouts/nav/project_insights_link' = render_if_exists 'layouts/nav/project_insights_link'
......
...@@ -4,12 +4,12 @@ ...@@ -4,12 +4,12 @@
.col-md-10.offset-md-1 .col-md-10.offset-md-1
.row.overview-details .row.overview-details
.col-md-6.overview-text .col-md-6.overview-text
%h4 Introducing Cycle Analytics %h4 Introducing Value Stream Analytics
%p %p
Cycle Analytics gives an overview of how much time it takes to go from idea to production in your project. Value Stream Analytics (VSA) gives an overview of how much time it takes to go from idea to production in your project.
To set up CA, you must first define a production environment by setting up your CI and then deploy to production. To set up VSA, you must first define a production environment by setting up your CI and then deploy to production.
%p %p
%a.btn{ href: help_page_path('user/analytics/cycle_analytics.md'), target: '_blank' } Read more %a.btn{ href: help_page_path('user/analytics/value_stream_analytics.md'), target: '_blank' } Read more
.col-md-6.overview-image .col-md-6.overview-image
%span.overview-icon %span.overview-icon
= custom_icon ('icon_cycle_analytics_overview') = custom_icon ('icon_cycle_analytics_overview')
- page_title "Cycle Analytics" - page_title "Value Stream Analytics"
#cycle-analytics{ "v-cloak" => "true", data: { request_path: project_cycle_analytics_path(@project) } } #cycle-analytics{ "v-cloak" => "true", data: { request_path: project_cycle_analytics_path(@project) } }
- if @cycle_analytics_no_data - if @cycle_analytics_no_data
%banner{ "v-if" => "!isOverviewDialogDismissed", %banner{ "v-if" => "!isOverviewDialogDismissed",
"documentation-link": help_page_path('user/analytics/cycle_analytics.md'), "documentation-link": help_page_path('user/analytics/value_stream_analytics.md'),
"v-on:dismiss-overview-dialog" => "dismissOverviewDialog()" } "v-on:dismiss-overview-dialog" => "dismissOverviewDialog()" }
= icon("spinner spin", "v-show" => "isLoading") = icon("spinner spin", "v-show" => "isLoading")
.wrapper{ "v-show" => "!isLoading && !hasError" } .wrapper{ "v-show" => "!isLoading && !hasError" }
......
---
title: Rename cycle analytics interfaces to value stream analytics
merge_request: 23427
author:
type: changed
...@@ -195,9 +195,8 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do ...@@ -195,9 +195,8 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
end end
end end
resource :cycle_analytics, only: [:show] resource :cycle_analytics, only: :show, path: 'value_stream_analytics'
scope module: :cycle_analytics, as: 'cycle_analytics', path: 'value_stream_analytics' do
namespace :cycle_analytics do
scope :events, controller: 'events' do scope :events, controller: 'events' do
get :issue get :issue
get :plan get :plan
...@@ -208,6 +207,7 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do ...@@ -208,6 +207,7 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
get :production get :production
end end
end end
get '/cycle_analytics', to: redirect('%{namespace_id}/%{project_id}/-/value_stream_analytics')
concerns :clusterable concerns :clusterable
......
...@@ -109,7 +109,7 @@ class Gitlab::Seeder::CycleAnalytics ...@@ -109,7 +109,7 @@ class Gitlab::Seeder::CycleAnalytics
def create_issues def create_issues
Array.new(@issue_count) do Array.new(@issue_count) do
issue_params = { issue_params = {
title: "Cycle Analytics: #{FFaker::Lorem.sentence(6)}", title: "Value Stream Analytics: #{FFaker::Lorem.sentence(6)}",
description: FFaker::Lorem.sentence, description: FFaker::Lorem.sentence,
state: 'opened', state: 'opened',
assignees: [@project.team.users.sample] assignees: [@project.team.users.sample]
...@@ -166,7 +166,7 @@ class Gitlab::Seeder::CycleAnalytics ...@@ -166,7 +166,7 @@ class Gitlab::Seeder::CycleAnalytics
Timecop.travel 12.hours.from_now Timecop.travel 12.hours.from_now
opts = { opts = {
title: 'Cycle Analytics merge_request', title: 'Value Stream Analytics merge_request',
description: "Fixes #{issue.to_reference}", description: "Fixes #{issue.to_reference}",
source_branch: branch, source_branch: branch,
target_branch: 'master' target_branch: 'master'
......
...@@ -88,7 +88,7 @@ The following documentation relates to the DevOps **Manage** stage: ...@@ -88,7 +88,7 @@ The following documentation relates to the DevOps **Manage** stage:
| Manage Topics | Description | | Manage Topics | Description |
|:--------------------------------------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |:--------------------------------------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [Authentication and<br/>Authorization](administration/auth/README.md) **(CORE ONLY)** | Supported authentication and authorization providers. | | [Authentication and<br/>Authorization](administration/auth/README.md) **(CORE ONLY)** | Supported authentication and authorization providers. |
| [GitLab Cycle Analytics](user/project/cycle_analytics.md) | Measure the time it takes to go from an [idea to production](https://about.gitlab.com/blog/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/#from-idea-to-production-with-gitlab) for each project you have. | | [GitLab Value Stream Analytics](user/project/cycle_analytics.md) | Measure the time it takes to go from an [idea to production](https://about.gitlab.com/blog/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/#from-idea-to-production-with-gitlab) for each project you have. |
| [Instance Statistics](user/instance_statistics/index.md) | Discover statistics on how many GitLab features you use and user activity. | | [Instance Statistics](user/instance_statistics/index.md) | Discover statistics on how many GitLab features you use and user activity. |
<div align="right"> <div align="right">
......
...@@ -220,7 +220,7 @@ deployment will be recorded as a new environment named `production`. ...@@ -220,7 +220,7 @@ deployment will be recorded as a new environment named `production`.
NOTE: **Note:** NOTE: **Note:**
If your environment's name is `production` (all lowercase), If your environment's name is `production` (all lowercase),
it will get recorded in [Cycle Analytics](../user/project/cycle_analytics.md). it will get recorded in [Value Stream Analytics](../user/project/cycle_analytics.md).
### Configuring dynamic environments ### Configuring dynamic environments
......
...@@ -80,7 +80,7 @@ Complementary reads: ...@@ -80,7 +80,7 @@ Complementary reads:
- [File uploads](uploads.md) - [File uploads](uploads.md)
- [Auto DevOps development guide](auto_devops.md) - [Auto DevOps development guide](auto_devops.md)
- [Mass Inserting Models](mass_insert.md) - [Mass Inserting Models](mass_insert.md)
- [Cycle Analytics development guide](cycle_analytics.md) - [Value Stream Analytics development guide](value_stream_analytics.md)
- [Issue types vs first-class types](issue_types.md) - [Issue types vs first-class types](issue_types.md)
- [Application limits](application_limits.md) - [Application limits](application_limits.md)
- [Redis guidelines](redis.md) - [Redis guidelines](redis.md)
......
This diff is collapsed.
...@@ -559,5 +559,5 @@ Let's suppose you want to add translations for a new language, let's say French. ...@@ -559,5 +559,5 @@ Let's suppose you want to add translations for a new language, let's say French.
```shell ```shell
git add locale/fr/ app/assets/javascripts/locale/fr/ git add locale/fr/ app/assets/javascripts/locale/fr/
git commit -m "Add French translations for Cycle Analytics page" git commit -m "Add French translations for Value Stream Analytics page"
``` ```
This diff is collapsed.
...@@ -36,7 +36,7 @@ identify improvements that might substantially accelerate your development cycle ...@@ -36,7 +36,7 @@ identify improvements that might substantially accelerate your development cycle
Code Review Analytics can be used when: Code Review Analytics can be used when:
- Your team agrees that code review is moving too slow. - Your team agrees that code review is moving too slow.
- The [Cycle Analytics feature](cycle_analytics.md) shows that reviews are your team's most time-consuming step. - The [Value Stream Analytics feature](value_stream_analytics.md) shows that reviews are your team's most time-consuming step.
You can use Code Review Analytics to see the types of work that are currently moving the slowest, and analyze the patterns You can use Code Review Analytics to see the types of work that are currently moving the slowest, and analyze the patterns
and trends between them. For example: and trends between them. For example:
......
This diff is collapsed.
...@@ -16,13 +16,13 @@ Once enabled, click on **Analytics** from the top navigation bar. ...@@ -16,13 +16,13 @@ Once enabled, click on **Analytics** from the top navigation bar.
From the centralized analytics workspace, the following analytics are available: From the centralized analytics workspace, the following analytics are available:
- [Code Review Analytics](code_review_analytics.md). **(STARTER)** - [Code Review Analytics](code_review_analytics.md). **(STARTER)**
- [Cycle Analytics](cycle_analytics.md), enabled with the `cycle_analytics` - [Value Stream Analytics](value_stream_analytics.md), enabled with the `cycle_analytics`
[feature flag](../../development/feature_flags/development.md#enabling-a-feature-flag-in-development). **(PREMIUM)** [feature flag](../../development/feature_flags/development.md#enabling-a-feature-flag-in-development). **(PREMIUM)**
- [Productivity Analytics](productivity_analytics.md), enabled with the `productivity_analytics` - [Productivity Analytics](productivity_analytics.md), enabled with the `productivity_analytics`
[feature flag](../../development/feature_flags/development.md#enabling-a-feature-flag-in-development). **(PREMIUM)** [feature flag](../../development/feature_flags/development.md#enabling-a-feature-flag-in-development). **(PREMIUM)**
NOTE: **Note:** NOTE: **Note:**
Project-level Cycle Analytics are still available at a project's **Project > Cycle Analytics**. Project-level Value Stream Analytics are still available at a project's **Project > Value Stream Analytics**.
## Other analytics tools ## Other analytics tools
......
...@@ -7,7 +7,7 @@ Track development velocity with Productivity Analytics. ...@@ -7,7 +7,7 @@ Track development velocity with Productivity Analytics.
For many companies, the development cycle is a blackbox and getting an estimate of how For many companies, the development cycle is a blackbox and getting an estimate of how
long, on average, it takes to deliver features is an enormous endeavor. long, on average, it takes to deliver features is an enormous endeavor.
While [Cycle Analytics](../project/cycle_analytics.md) focuses on the entire While [Value Stream Analytics](../project/cycle_analytics.md) focuses on the entire
Software Development Life Cycle (SDLC) process, Productivity Analytics provides a way for Engineering Management to drill down in a systematic way to uncover patterns and causes for success or failure at an individual, project or group level. Software Development Life Cycle (SDLC) process, Productivity Analytics provides a way for Engineering Management to drill down in a systematic way to uncover patterns and causes for success or failure at an individual, project or group level.
Productivity can slow down for many reasons ranging from degrading code base to quickly growing teams. In order to investigate, department or team leaders can start by visualizing the time it takes for merge requests to be merged. Productivity can slow down for many reasons ranging from degrading code base to quickly growing teams. In order to investigate, department or team leaders can start by visualizing the time it takes for merge requests to be merged.
......
This diff is collapsed.
...@@ -45,7 +45,7 @@ GitLab is a Git-based platform that integrates a great number of essential tools ...@@ -45,7 +45,7 @@ GitLab is a Git-based platform that integrates a great number of essential tools
- Building, testing, and deploying with built-in [Continuous Integration](../ci/README.md). - Building, testing, and deploying with built-in [Continuous Integration](../ci/README.md).
- Deploying personal and professional static websites with [GitLab Pages](project/pages/index.md). - Deploying personal and professional static websites with [GitLab Pages](project/pages/index.md).
- Integrating with Docker by using [GitLab Container Registry](packages/container_registry/index.md). - Integrating with Docker by using [GitLab Container Registry](packages/container_registry/index.md).
- Tracking the development lifecycle by using [GitLab Cycle Analytics](project/cycle_analytics.md). - Tracking the development lifecycle by using [GitLab Value Stream Analytics](project/cycle_analytics.md).
With GitLab Enterprise Edition, you can also: With GitLab Enterprise Edition, you can also:
......
...@@ -166,10 +166,10 @@ Maintainers and Developers from pushing to a protected branch. Read through the ...@@ -166,10 +166,10 @@ Maintainers and Developers from pushing to a protected branch. Read through the
[Allowed to Merge and Allowed to Push settings](project/protected_branches.md#using-the-allowed-to-merge-and-allowed-to-push-settings) [Allowed to Merge and Allowed to Push settings](project/protected_branches.md#using-the-allowed-to-merge-and-allowed-to-push-settings)
to learn more. to learn more.
### Cycle Analytics permissions ### Value Stream Analytics permissions
Find the current permissions on the Cycle Analytics dashboard on Find the current permissions on the Value Stream Analytics dashboard, as described in
the [documentation on Cycle Analytics permissions](analytics/cycle_analytics.md#permissions). [related documentation](analytics/value_stream_analytics.md#permissions).
### Issue Board permissions ### Issue Board permissions
......
--- ---
redirect_to: '../analytics/cycle_analytics.md' redirect_to: '../analytics/value_stream_analytics.md'
--- ---
This document was moved to [another location](../analytics/cycle_analytics.md) This document was moved to [another location](../analytics/value_stream_analytics.md)
...@@ -87,7 +87,7 @@ When you create a project in GitLab, you'll have access to a large number of ...@@ -87,7 +87,7 @@ When you create a project in GitLab, you'll have access to a large number of
- [Wiki](wiki/index.md): document your GitLab project in an integrated Wiki. - [Wiki](wiki/index.md): document your GitLab project in an integrated Wiki.
- [Snippets](../snippets.md): store, share and collaborate on code snippets. - [Snippets](../snippets.md): store, share and collaborate on code snippets.
- [Cycle Analytics](cycle_analytics.md): review your development lifecycle. - [Value Stream Analytics](cycle_analytics.md): review your development lifecycle.
- [Insights](insights/index.md): configure the Insights that matter for your projects. **(ULTIMATE)** - [Insights](insights/index.md): configure the Insights that matter for your projects. **(ULTIMATE)**
- [Security Dashboard](security_dashboard.md): Security Dashboard. **(ULTIMATE)** - [Security Dashboard](security_dashboard.md): Security Dashboard. **(ULTIMATE)**
- [Syntax highlighting](highlighting.md): an alternative to customize - [Syntax highlighting](highlighting.md): an alternative to customize
......
...@@ -203,7 +203,7 @@ export default { ...@@ -203,7 +203,7 @@ export default {
<template> <template>
<div class="js-cycle-analytics"> <div class="js-cycle-analytics">
<div class="page-title-holder d-flex align-items-center"> <div class="page-title-holder d-flex align-items-center">
<h3 class="page-title">{{ __('Cycle Analytics') }}</h3> <h3 class="page-title">{{ __('Value Stream Analytics') }}</h3>
</div> </div>
<div class="mw-100"> <div class="mw-100">
<div <div
...@@ -239,7 +239,7 @@ export default { ...@@ -239,7 +239,7 @@ export default {
</div> </div>
<gl-empty-state <gl-empty-state
v-if="shouldRenderEmptyState" v-if="shouldRenderEmptyState"
:title="__('Cycle Analytics can help you determine your team’s velocity')" :title="__('Value Stream Analytics can help you determine your team’s velocity')"
:description=" :description="
__( __(
'Start by choosing a group to see how your team is spending time. You can then drill down to the project level.', 'Start by choosing a group to see how your team is spending time. You can then drill down to the project level.',
...@@ -251,11 +251,11 @@ export default { ...@@ -251,11 +251,11 @@ export default {
<gl-empty-state <gl-empty-state
v-if="hasNoAccessError" v-if="hasNoAccessError"
class="js-empty-state" class="js-empty-state"
:title="__('You don’t have access to Cycle Analytics for this group')" :title="__('You don’t have access to Value Stream Analytics for this group')"
:svg-path="noAccessSvgPath" :svg-path="noAccessSvgPath"
:description=" :description="
__( __(
'Only \'Reporter\' roles and above on tiers Premium / Silver and above can see Cycle Analytics.', 'Only \'Reporter\' roles and above on tiers Premium / Silver and above can see Value Stream Analytics.',
) )
" "
/> />
......
...@@ -14,7 +14,7 @@ export default { ...@@ -14,7 +14,7 @@ export default {
}, },
setSelectedGroup(selectedGroup) { setSelectedGroup(selectedGroup) {
this.selectedGroup = selectedGroup; this.selectedGroup = selectedGroup;
this.renderSelectedGroup(`/groups/${selectedGroup.path}/-/cycle_analytics`); this.renderSelectedGroup(`/groups/${selectedGroup.path}/-/value_stream_analytics`);
}, },
setSelectedProjects(selectedProjects) { setSelectedProjects(selectedProjects) {
this.selectedProjectIds = selectedProjects.map(value => value.id); this.selectedProjectIds = selectedProjects.map(value => value.id);
......
...@@ -119,7 +119,7 @@ export const receiveCycleAnalyticsDataError = ({ commit }, { response }) => { ...@@ -119,7 +119,7 @@ export const receiveCycleAnalyticsDataError = ({ commit }, { response }) => {
commit(types.RECEIVE_CYCLE_ANALYTICS_DATA_ERROR, status); commit(types.RECEIVE_CYCLE_ANALYTICS_DATA_ERROR, status);
if (status !== httpStatus.FORBIDDEN) if (status !== httpStatus.FORBIDDEN)
createFlash(__('There was an error while fetching cycle analytics data.')); createFlash(__('There was an error while fetching value stream analytics data.'));
}; };
export const fetchCycleAnalyticsData = ({ dispatch }) => { export const fetchCycleAnalyticsData = ({ dispatch }) => {
...@@ -147,7 +147,7 @@ export const requestSummaryData = ({ commit }) => commit(types.REQUEST_SUMMARY_D ...@@ -147,7 +147,7 @@ export const requestSummaryData = ({ commit }) => commit(types.REQUEST_SUMMARY_D
export const receiveSummaryDataError = ({ commit }, error) => { export const receiveSummaryDataError = ({ commit }, error) => {
commit(types.RECEIVE_SUMMARY_DATA_ERROR, error); commit(types.RECEIVE_SUMMARY_DATA_ERROR, error);
createFlash(__('There was an error while fetching cycle analytics summary data.')); createFlash(__('There was an error while fetching value stream analytics summary data.'));
}; };
export const receiveSummaryDataSuccess = ({ commit }, data) => export const receiveSummaryDataSuccess = ({ commit }, data) =>
...@@ -198,7 +198,7 @@ export const fetchGroupLabels = ({ dispatch, state }) => { ...@@ -198,7 +198,7 @@ export const fetchGroupLabels = ({ dispatch, state }) => {
export const receiveGroupStagesAndEventsError = ({ commit }, error) => { export const receiveGroupStagesAndEventsError = ({ commit }, error) => {
commit(types.RECEIVE_GROUP_STAGES_AND_EVENTS_ERROR, error); commit(types.RECEIVE_GROUP_STAGES_AND_EVENTS_ERROR, error);
createFlash(__('There was an error fetching cycle analytics stages.')); createFlash(__('There was an error fetching value stream analytics stages.'));
}; };
export const receiveGroupStagesAndEventsSuccess = ({ state, commit, dispatch }, data) => { export const receiveGroupStagesAndEventsSuccess = ({ state, commit, dispatch }, data) => {
...@@ -209,7 +209,7 @@ export const receiveGroupStagesAndEventsSuccess = ({ state, commit, dispatch }, ...@@ -209,7 +209,7 @@ export const receiveGroupStagesAndEventsSuccess = ({ state, commit, dispatch },
dispatch('setSelectedStage', firstStage); dispatch('setSelectedStage', firstStage);
dispatch('fetchStageData', firstStage.slug); dispatch('fetchStageData', firstStage.slug);
} else { } else {
createFlash(__('There was an error while fetching cycle analytics data.')); createFlash(__('There was an error while fetching value stream analytics data.'));
} }
}; };
...@@ -386,7 +386,7 @@ export const receiveDurationDataSuccess = ({ commit, state, dispatch }, data) => ...@@ -386,7 +386,7 @@ export const receiveDurationDataSuccess = ({ commit, state, dispatch }, data) =>
export const receiveDurationDataError = ({ commit }) => { export const receiveDurationDataError = ({ commit }) => {
commit(types.RECEIVE_DURATION_DATA_ERROR); commit(types.RECEIVE_DURATION_DATA_ERROR);
createFlash(__('There was an error while fetching cycle analytics duration data.')); createFlash(__('There was an error while fetching value stream analytics duration data.'));
}; };
export const fetchDurationData = ({ state, dispatch, getters }) => { export const fetchDurationData = ({ state, dispatch, getters }) => {
...@@ -430,7 +430,7 @@ export const receiveDurationMedianDataSuccess = ({ commit }, data) => ...@@ -430,7 +430,7 @@ export const receiveDurationMedianDataSuccess = ({ commit }, data) =>
export const receiveDurationMedianDataError = ({ commit }) => { export const receiveDurationMedianDataError = ({ commit }) => {
commit(types.RECEIVE_DURATION_MEDIAN_DATA_ERROR); commit(types.RECEIVE_DURATION_MEDIAN_DATA_ERROR);
createFlash(__('There was an error while fetching cycle analytics duration median data.')); createFlash(__('There was an error while fetching value stream analytics duration median data.'));
}; };
export const fetchDurationMedianData = ({ state, dispatch }) => { export const fetchDurationMedianData = ({ state, dispatch }) => {
......
...@@ -45,7 +45,7 @@ export const getLabelEventsIdentifiers = (events = []) => ...@@ -45,7 +45,7 @@ export const getLabelEventsIdentifiers = (events = []) =>
/** /**
* Checks if the specified stage is in memory or persisted to storage based on the id * Checks if the specified stage is in memory or persisted to storage based on the id
* *
* Default cycle analytics stages are initially stored in memory, when they are first * Default value stream analytics stages are initially stored in memory, when they are first
* created the id for the stage is the name of the stage in lowercase. This string id * created the id for the stage is the name of the stage in lowercase. This string id
* is used to fetch stage data (events, median calculation) * is used to fetch stage data (events, median calculation)
* *
......
...@@ -17,12 +17,13 @@ export default { ...@@ -17,12 +17,13 @@ export default {
projectPackagesPath: '/api/:version/projects/:id/packages', projectPackagesPath: '/api/:version/projects/:id/packages',
projectPackagePath: '/api/:version/projects/:id/packages/:package_id', projectPackagePath: '/api/:version/projects/:id/packages/:package_id',
cycleAnalyticsTasksByTypePath: '/-/analytics/type_of_work/tasks_by_type', cycleAnalyticsTasksByTypePath: '/-/analytics/type_of_work/tasks_by_type',
cycleAnalyticsSummaryDataPath: '/-/analytics/cycle_analytics/summary', cycleAnalyticsSummaryDataPath: '/-/analytics/value_stream_analytics/summary',
cycleAnalyticsGroupStagesAndEventsPath: '/-/analytics/cycle_analytics/stages', cycleAnalyticsGroupStagesAndEventsPath: '/-/analytics/value_stream_analytics/stages',
cycleAnalyticsStageEventsPath: '/-/analytics/cycle_analytics/stages/:stage_id/records', cycleAnalyticsStageEventsPath: '/-/analytics/value_stream_analytics/stages/:stage_id/records',
cycleAnalyticsStageMedianPath: '/-/analytics/cycle_analytics/stages/:stage_id/median', cycleAnalyticsStageMedianPath: '/-/analytics/value_stream_analytics/stages/:stage_id/median',
cycleAnalyticsStagePath: '/-/analytics/cycle_analytics/stages/:stage_id', cycleAnalyticsStagePath: '/-/analytics/value_stream_analytics/stages/:stage_id',
cycleAnalyticsDurationChartPath: '/-/analytics/cycle_analytics/stages/:stage_id/duration_chart', cycleAnalyticsDurationChartPath:
'/-/analytics/value_stream_analytics/stages/:stage_id/duration_chart',
codeReviewAnalyticsPath: '/api/:version/analytics/code_review', codeReviewAnalyticsPath: '/api/:version/analytics/code_review',
countriesPath: '/-/countries', countriesPath: '/-/countries',
countryStatesPath: '/-/country_states', countryStatesPath: '/-/country_states',
......
- page_title _("Cycle Analytics") - page_title _("Value Stream Analytics")
- initial_data = @request_params.valid? ? @request_params.to_data_attributes : {} - initial_data = @request_params.valid? ? @request_params.to_data_attributes : {}
#js-cycle-analytics-app{ data: initial_data.merge({ empty_state_svg_path: image_path("illustrations/analytics/cycle-analytics-empty-chart.svg"), #js-cycle-analytics-app{ data: initial_data.merge({ empty_state_svg_path: image_path("illustrations/analytics/cycle-analytics-empty-chart.svg"),
......
...@@ -25,12 +25,12 @@ ...@@ -25,12 +25,12 @@
.nav-icon-container .nav-icon-container
= sprite_icon('repeat') = sprite_icon('repeat')
%span.nav-item-name %span.nav-item-name
= _('Cycle Analytics') = _('Value Stream Analytics')
%ul.sidebar-sub-level-items.is-fly-out-only %ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(controller: :cycle_analytics, html_options: { class: "fly-out-top-item qa-sidebar-cycle-analytics-fly-out" } ) do = nav_link(controller: :cycle_analytics, html_options: { class: "fly-out-top-item qa-sidebar-cycle-analytics-fly-out" } ) do
= link_to analytics_cycle_analytics_path do = link_to analytics_cycle_analytics_path do
%strong.fly-out-top-item-name %strong.fly-out-top-item-name
= _('Cycle Analytics') = _('Value Stream Analytics')
= render_ce 'layouts/nav/sidebar/instance_statistics_links' = render_ce 'layouts/nav/sidebar/instance_statistics_links'
......
...@@ -6,8 +6,8 @@ namespace :analytics do ...@@ -6,8 +6,8 @@ namespace :analytics do
resource :productivity_analytics, only: :show, constraints: -> (req) { Feature.disabled?(:group_level_productivity_analytics) && Gitlab::Analytics.productivity_analytics_enabled? } resource :productivity_analytics, only: :show, constraints: -> (req) { Feature.disabled?(:group_level_productivity_analytics) && Gitlab::Analytics.productivity_analytics_enabled? }
constraints(-> (req) { Gitlab::Analytics.cycle_analytics_enabled? }) do constraints(-> (req) { Gitlab::Analytics.cycle_analytics_enabled? }) do
resource :cycle_analytics, only: :show resource :cycle_analytics, only: :show, path: 'value_stream_analytics'
namespace :cycle_analytics do scope module: :cycle_analytics, as: 'cycle_analytics', path: 'value_stream_analytics' do
resources :stages, only: [:index, :create, :update, :destroy] do resources :stages, only: [:index, :create, :update, :destroy] do
member do member do
get :duration_chart get :duration_chart
...@@ -15,8 +15,9 @@ namespace :analytics do ...@@ -15,8 +15,9 @@ namespace :analytics do
get :records get :records
end end
end end
resource :summary, controller: :summary, only: [:show] resource :summary, controller: :summary, only: :show
end end
get '/cycle_analytics', to: redirect('-/analytics/value_stream_analytics')
end end
constraints(::Constraints::FeatureConstrainer.new(Gitlab::Analytics::TASKS_BY_TYPE_CHART_FEATURE_FLAG)) do constraints(::Constraints::FeatureConstrainer.new(Gitlab::Analytics::TASKS_BY_TYPE_CHART_FEATURE_FLAG)) do
......
...@@ -19,8 +19,8 @@ constraints(::Constraints::GroupUrlConstrainer.new) do ...@@ -19,8 +19,8 @@ constraints(::Constraints::GroupUrlConstrainer.new) do
get '/analytics', to: redirect('groups/%{group_id}/-/contribution_analytics') get '/analytics', to: redirect('groups/%{group_id}/-/contribution_analytics')
resource :contribution_analytics, only: [:show] resource :contribution_analytics, only: [:show]
resource :cycle_analytics, only: [:show] resource :cycle_analytics, only: [:show], path: 'value_stream_analytics'
namespace :cycle_analytics do scope module: :cycle_analytics, as: 'cycle_analytics', path: 'value_stream_analytics' do
scope :events, controller: 'events' do scope :events, controller: 'events' do
get :issue get :issue
get :plan get :plan
......
...@@ -160,7 +160,7 @@ class Gitlab::Seeder::CustomizableCycleAnalytics ...@@ -160,7 +160,7 @@ class Gitlab::Seeder::CustomizableCycleAnalytics
def merge_requests def merge_requests
@merge_requests ||= Array.new(MERGE_REQUEST_COUNT).map do |i| @merge_requests ||= Array.new(MERGE_REQUEST_COUNT).map do |i|
opts = { opts = {
title: 'Customized Cycle Analytics merge_request', title: 'Customized Value Stream Analytics merge_request',
description: "some description", description: "some description",
source_branch: "#{FFaker::Lorem.word}-#{i}-#{SecureRandom.hex(5)}", source_branch: "#{FFaker::Lorem.word}-#{i}-#{SecureRandom.hex(5)}",
target_branch: 'master' target_branch: 'master'
......
...@@ -16,7 +16,7 @@ describe Analytics::AnalyticsController do ...@@ -16,7 +16,7 @@ describe Analytics::AnalyticsController do
describe 'GET index' do describe 'GET index' do
describe 'redirects to the first enabled analytics page' do describe 'redirects to the first enabled analytics page' do
it 'redirects to cycle analytics' do it 'redirects to value stream analytics' do
stub_feature_flags(Gitlab::Analytics::CYCLE_ANALYTICS_FEATURE_FLAG => true) stub_feature_flags(Gitlab::Analytics::CYCLE_ANALYTICS_FEATURE_FLAG => true)
get :index get :index
......
# frozen_string_literal: true # frozen_string_literal: true
require 'spec_helper' require 'spec_helper'
describe 'Group Cycle Analytics', :js do describe 'Group Value Stream Analytics', :js do
let!(:user) { create(:user) } let!(:user) { create(:user) }
let!(:group) { create(:group, name: "CA-test-group") } let!(:group) { create(:group, name: "CA-test-group") }
let!(:project) { create(:project, :repository, namespace: group, group: group, name: "Cool fun project") } let!(:project) { create(:project, :repository, namespace: group, group: group, name: "Cool fun project") }
...@@ -32,7 +32,7 @@ describe 'Group Cycle Analytics', :js do ...@@ -32,7 +32,7 @@ describe 'Group Cycle Analytics', :js do
it 'displays an empty state before a group is selected' do it 'displays an empty state before a group is selected' do
element = page.find('.row.empty-state') element = page.find('.row.empty-state')
expect(element).to have_content("Cycle Analytics can help you determine your team’s velocity") expect(element).to have_content("Value Stream Analytics can help you determine your team’s velocity")
expect(element.find('.svg-content img')['src']).to have_content('illustrations/analytics/cycle-analytics-empty-chart') expect(element.find('.svg-content img')['src']).to have_content('illustrations/analytics/cycle-analytics-empty-chart')
end end
...@@ -78,7 +78,7 @@ describe 'Group Cycle Analytics', :js do ...@@ -78,7 +78,7 @@ describe 'Group Cycle Analytics', :js do
it 'displays empty text' do it 'displays empty text' do
[ [
'Cycle Analytics can help you determine your team’s velocity', 'Value Stream Analytics can help you determine your team’s velocity',
'Start by choosing a group to see how your team is spending time. You can then drill down to the project level.' 'Start by choosing a group to see how your team is spending time. You can then drill down to the project level.'
].each do |content| ].each do |content|
expect(page).to have_content(content) expect(page).to have_content(content)
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
}, },
{ {
"highlight": false, "highlight": false,
"title": "Cycle Analytics" "title": "Value Stream Analytics"
}, },
{ {
"highlight": false, "highlight": false,
......
...@@ -424,12 +424,12 @@ describe('Cycle Analytics component', () => { ...@@ -424,12 +424,12 @@ describe('Cycle Analytics component', () => {
const defaultRequests = { const defaultRequests = {
fetchSummaryData: { fetchSummaryData: {
status: defaultStatus, status: defaultStatus,
endpoint: `/-/analytics/cycle_analytics/summary`, endpoint: `/-/analytics/value_stream_analytics/summary`,
response: [...mockData.summaryData], response: [...mockData.summaryData],
}, },
fetchGroupStagesAndEvents: { fetchGroupStagesAndEvents: {
status: defaultStatus, status: defaultStatus,
endpoint: `/-/analytics/cycle_analytics/stages`, endpoint: `/-/analytics/value_stream_analytics/stages`,
response: { ...mockData.customizableStagesAndEvents }, response: { ...mockData.customizableStagesAndEvents },
}, },
fetchGroupLabels: { fetchGroupLabels: {
...@@ -448,19 +448,19 @@ describe('Cycle Analytics component', () => { ...@@ -448,19 +448,19 @@ describe('Cycle Analytics component', () => {
if (mockFetchDurationData) { if (mockFetchDurationData) {
mock mock
.onGet(/analytics\/cycle_analytics\/stages\/\d+\/duration_chart/) .onGet(/analytics\/value_stream_analytics\/stages\/\d+\/duration_chart/)
.reply(defaultStatus, [...mockData.rawDurationData]); .reply(defaultStatus, [...mockData.rawDurationData]);
} }
if (mockFetchStageMedian) { if (mockFetchStageMedian) {
mock mock
.onGet(/analytics\/cycle_analytics\/stages\/\d+\/median/) .onGet(/analytics\/value_stream_analytics\/stages\/\d+\/median/)
.reply(defaultStatus, { value: null }); .reply(defaultStatus, { value: null });
} }
if (mockFetchStageData) { if (mockFetchStageData) {
mock mock
.onGet(/analytics\/cycle_analytics\/stages\/\d+\/records/) .onGet(/analytics\/value_stream_analytics\/stages\/\d+\/records/)
.reply(defaultStatus, mockData.issueEvents); .reply(defaultStatus, mockData.issueEvents);
} }
...@@ -497,14 +497,14 @@ describe('Cycle Analytics component', () => { ...@@ -497,14 +497,14 @@ describe('Cycle Analytics component', () => {
overrides: { overrides: {
fetchSummaryData: { fetchSummaryData: {
status: httpStatusCodes.NOT_FOUND, status: httpStatusCodes.NOT_FOUND,
endpoint: '/-/analytics/cycle_analytics/summary', endpoint: '/-/analytics/value_stream_analytics/summary',
response: { response: { status: httpStatusCodes.NOT_FOUND } }, response: { response: { status: httpStatusCodes.NOT_FOUND } },
}, },
}, },
}); });
return selectGroupAndFindError( return selectGroupAndFindError(
'There was an error while fetching cycle analytics summary data.', 'There was an error while fetching value stream analytics summary data.',
); );
}); });
...@@ -531,14 +531,14 @@ describe('Cycle Analytics component', () => { ...@@ -531,14 +531,14 @@ describe('Cycle Analytics component', () => {
mockRequestCycleAnalyticsData({ mockRequestCycleAnalyticsData({
overrides: { overrides: {
fetchGroupStagesAndEvents: { fetchGroupStagesAndEvents: {
endPoint: '/-/analytics/cycle_analytics/stages', endPoint: '/-/analytics/value_stream_analytics/stages',
status: httpStatusCodes.NOT_FOUND, status: httpStatusCodes.NOT_FOUND,
response: { response: { status: httpStatusCodes.NOT_FOUND } }, response: { response: { status: httpStatusCodes.NOT_FOUND } },
}, },
}, },
}); });
return selectGroupAndFindError('There was an error fetching cycle analytics stages.'); return selectGroupAndFindError('There was an error fetching value stream analytics stages.');
}); });
it('will display an error if the fetchStageData request fails', () => { it('will display an error if the fetchStageData request fails', () => {
...@@ -572,7 +572,7 @@ describe('Cycle Analytics component', () => { ...@@ -572,7 +572,7 @@ describe('Cycle Analytics component', () => {
return waitForPromises().catch(() => { return waitForPromises().catch(() => {
expect(findFlashError().innerText.trim()).toEqual( expect(findFlashError().innerText.trim()).toEqual(
'There was an error while fetching cycle analytics duration data.', 'There was an error while fetching value stream analytics duration data.',
); );
}); });
}); });
...@@ -588,7 +588,7 @@ describe('Cycle Analytics component', () => { ...@@ -588,7 +588,7 @@ describe('Cycle Analytics component', () => {
return waitForPromises().catch(() => { return waitForPromises().catch(() => {
expect(findFlashError().innerText.trim()).toEqual( expect(findFlashError().innerText.trim()).toEqual(
'There was an error while fetching cycle analytics duration data.', 'There was an error while fetching value stream analytics duration data.',
); );
}); });
}); });
......
...@@ -4,7 +4,7 @@ import { groupLabels } from '../mock_data'; ...@@ -4,7 +4,7 @@ import { groupLabels } from '../mock_data';
const selectedLabel = groupLabels[groupLabels.length - 1]; const selectedLabel = groupLabels[groupLabels.length - 1];
describe('Cycle Analytics LabelsSelector', () => { describe('Value Stream Analytics LabelsSelector', () => {
function createComponent({ props = {}, shallow = true } = {}) { function createComponent({ props = {}, shallow = true } = {}) {
const func = shallow ? shallowMount : mount; const func = shallow ? shallowMount : mount;
return func(LabelsSelector, { return func(LabelsSelector, {
......
...@@ -11,10 +11,10 @@ import { toYmd } from 'ee/analytics/shared/utils'; ...@@ -11,10 +11,10 @@ import { toYmd } from 'ee/analytics/shared/utils';
import { transformRawTasksByTypeData } from 'ee/analytics/cycle_analytics/utils'; import { transformRawTasksByTypeData } from 'ee/analytics/cycle_analytics/utils';
const endpoints = { const endpoints = {
customizableCycleAnalyticsStagesAndEvents: 'analytics/cycle_analytics/stages.json', // customizable stages and events endpoint customizableCycleAnalyticsStagesAndEvents: 'analytics/value_stream_analytics/stages.json', // customizable stages and events endpoint
stageEvents: stage => `analytics/cycle_analytics/stages/${stage}/records.json`, stageEvents: stage => `analytics/value_stream_analytics/stages/${stage}/records.json`,
stageMedian: stage => `analytics/cycle_analytics/stages/${stage}/median.json`, stageMedian: stage => `analytics/value_stream_analytics/stages/${stage}/median.json`,
summaryData: 'analytics/cycle_analytics/summary.json', summaryData: 'analytics/value_stream_analytics/summary.json',
}; };
export const groupLabels = mockLabels.map(({ title, ...rest }) => ({ ...rest, name: title })); export const groupLabels = mockLabels.map(({ title, ...rest }) => ({ ...rest, name: title }));
......
...@@ -22,20 +22,20 @@ import { ...@@ -22,20 +22,20 @@ import {
const stageData = { events: [] }; const stageData = { events: [] };
const error = new Error('Request failed with status code 404'); const error = new Error('Request failed with status code 404');
const flashErrorMessage = 'There was an error while fetching cycle analytics data.'; const flashErrorMessage = 'There was an error while fetching value stream analytics data.';
const selectedGroup = { fullPath: group.path }; const selectedGroup = { fullPath: group.path };
const [selectedStage] = stages; const [selectedStage] = stages;
const selectedStageSlug = selectedStage.slug; const selectedStageSlug = selectedStage.slug;
const endpoints = { const endpoints = {
groupLabels: `/groups/${group.path}/-/labels`, groupLabels: `/groups/${group.path}/-/labels`,
summaryData: '/analytics/cycle_analytics/summary', summaryData: '/analytics/value_stream_analytics/summary',
durationData: /analytics\/cycle_analytics\/stages\/\d+\/duration_chart/, durationData: /analytics\/value_stream_analytics\/stages\/\d+\/duration_chart/,
stageData: /analytics\/cycle_analytics\/stages\/\d+\/records/, stageData: /analytics\/value_stream_analytics\/stages\/\d+\/records/,
stageMedian: /analytics\/cycle_analytics\/stages\/\d+\/median/, stageMedian: /analytics\/value_stream_analytics\/stages\/\d+\/median/,
baseStagesEndpoint: '/analytics/cycle_analytics/stages', baseStagesEndpoint: '/analytics/value_stream_analytics/stages',
}; };
const stageEndpoint = ({ stageId }) => `/-/analytics/cycle_analytics/stages/${stageId}`; const stageEndpoint = ({ stageId }) => `/-/analytics/value_stream_analytics/stages/${stageId}`;
describe('Cycle analytics actions', () => { describe('Cycle analytics actions', () => {
let state; let state;
...@@ -276,7 +276,7 @@ describe('Cycle analytics actions', () => { ...@@ -276,7 +276,7 @@ describe('Cycle analytics actions', () => {
state = { ...state, selectedGroup, startDate, endDate }; state = { ...state, selectedGroup, startDate, endDate };
}); });
it(`dispatches actions for required cycle analytics data`, done => { it(`dispatches actions for required value stream analytics analytics data`, done => {
testAction( testAction(
actions.fetchCycleAnalyticsData, actions.fetchCycleAnalyticsData,
state, state,
...@@ -368,7 +368,9 @@ describe('Cycle analytics actions', () => { ...@@ -368,7 +368,9 @@ describe('Cycle analytics actions', () => {
commit: () => {}, commit: () => {},
}) })
.then(() => { .then(() => {
shouldFlashAMessage('There was an error while fetching cycle analytics summary data.'); shouldFlashAMessage(
'There was an error while fetching value stream analytics summary data.',
);
done(); done();
}) })
.catch(done.fail); .catch(done.fail);
...@@ -394,7 +396,7 @@ describe('Cycle analytics actions', () => { ...@@ -394,7 +396,7 @@ describe('Cycle analytics actions', () => {
commit: () => {}, commit: () => {},
}) })
.then(() => { .then(() => {
shouldFlashAMessage('There was an error fetching cycle analytics stages.'); shouldFlashAMessage('There was an error fetching value stream analytics stages.');
done(); done();
}) })
.catch(done.fail); .catch(done.fail);
...@@ -425,7 +427,9 @@ describe('Cycle analytics actions', () => { ...@@ -425,7 +427,9 @@ describe('Cycle analytics actions', () => {
{}, {},
); );
shouldFlashAMessage('There was an error while fetching cycle analytics duration data.'); shouldFlashAMessage(
'There was an error while fetching value stream analytics duration data.',
);
}); });
describe('with an existing error', () => { describe('with an existing error', () => {
...@@ -925,7 +929,9 @@ describe('Cycle analytics actions', () => { ...@@ -925,7 +929,9 @@ describe('Cycle analytics actions', () => {
commit: () => {}, commit: () => {},
}); });
shouldFlashAMessage('There was an error while fetching cycle analytics duration data.'); shouldFlashAMessage(
'There was an error while fetching value stream analytics duration data.',
);
}); });
}); });
...@@ -1149,7 +1155,7 @@ describe('Cycle analytics actions', () => { ...@@ -1149,7 +1155,7 @@ describe('Cycle analytics actions', () => {
}); });
shouldFlashAMessage( shouldFlashAMessage(
'There was an error while fetching cycle analytics duration median data.', 'There was an error while fetching value stream analytics duration median data.',
); );
}); });
}); });
......
...@@ -380,13 +380,13 @@ describe('Api', () => { ...@@ -380,13 +380,13 @@ describe('Api', () => {
}); });
describe('cycleAnalyticsSummaryData', () => { describe('cycleAnalyticsSummaryData', () => {
it('fetches cycle analytics summary data', done => { it('fetches value stream analytics summary data', done => {
const response = [{ value: 0, title: 'New Issues' }, { value: 0, title: 'Deploys' }]; const response = [{ value: 0, title: 'New Issues' }, { value: 0, title: 'Deploys' }];
const params = { const params = {
...defaultParams, ...defaultParams,
}; };
const expectedUrl = `${dummyUrlRoot}/-/analytics/cycle_analytics/summary`; const expectedUrl = `${dummyUrlRoot}/-/analytics/value_stream_analytics/summary`;
mock.onGet(expectedUrl).reply(200, response); mock.onGet(expectedUrl).reply(200, response);
Api.cycleAnalyticsSummaryData(params) Api.cycleAnalyticsSummaryData(params)
...@@ -410,7 +410,7 @@ describe('Api', () => { ...@@ -410,7 +410,7 @@ describe('Api', () => {
'cycle_analytics[created_after]': createdAfter, 'cycle_analytics[created_after]': createdAfter,
'cycle_analytics[created_before]': createdBefore, 'cycle_analytics[created_before]': createdBefore,
}; };
const expectedUrl = `${dummyUrlRoot}/-/analytics/cycle_analytics/stages`; const expectedUrl = `${dummyUrlRoot}/-/analytics/value_stream_analytics/stages`;
mock.onGet(expectedUrl).reply(200, response); mock.onGet(expectedUrl).reply(200, response);
Api.cycleAnalyticsGroupStagesAndEvents(groupId, params) Api.cycleAnalyticsGroupStagesAndEvents(groupId, params)
...@@ -432,7 +432,7 @@ describe('Api', () => { ...@@ -432,7 +432,7 @@ describe('Api', () => {
const params = { const params = {
...defaultParams, ...defaultParams,
}; };
const expectedUrl = `${dummyUrlRoot}/-/analytics/cycle_analytics/stages/${stageId}/records`; const expectedUrl = `${dummyUrlRoot}/-/analytics/value_stream_analytics/stages/${stageId}/records`;
mock.onGet(expectedUrl).reply(200, response); mock.onGet(expectedUrl).reply(200, response);
Api.cycleAnalyticsStageEvents(groupId, stageId, params) Api.cycleAnalyticsStageEvents(groupId, stageId, params)
...@@ -454,7 +454,7 @@ describe('Api', () => { ...@@ -454,7 +454,7 @@ describe('Api', () => {
const params = { const params = {
...defaultParams, ...defaultParams,
}; };
const expectedUrl = `${dummyUrlRoot}/-/analytics/cycle_analytics/stages/${stageId}/median`; const expectedUrl = `${dummyUrlRoot}/-/analytics/value_stream_analytics/stages/${stageId}/median`;
mock.onGet(expectedUrl).reply(200, response); mock.onGet(expectedUrl).reply(200, response);
Api.cycleAnalyticsStageMedian(groupId, stageId, params) Api.cycleAnalyticsStageMedian(groupId, stageId, params)
...@@ -480,7 +480,7 @@ describe('Api', () => { ...@@ -480,7 +480,7 @@ describe('Api', () => {
end_event_identifier: 'issue_closed', end_event_identifier: 'issue_closed',
end_event_label_id: null, end_event_label_id: null,
}; };
const expectedUrl = `${dummyUrlRoot}/-/analytics/cycle_analytics/stages`; const expectedUrl = `${dummyUrlRoot}/-/analytics/value_stream_analytics/stages`;
mock.onPost(expectedUrl).reply(200, response); mock.onPost(expectedUrl).reply(200, response);
Api.cycleAnalyticsCreateStage(groupId, customStage) Api.cycleAnalyticsCreateStage(groupId, customStage)
...@@ -502,7 +502,7 @@ describe('Api', () => { ...@@ -502,7 +502,7 @@ describe('Api', () => {
name: 'nice-stage', name: 'nice-stage',
hidden: true, hidden: true,
}; };
const expectedUrl = `${dummyUrlRoot}/-/analytics/cycle_analytics/stages/${stageId}`; const expectedUrl = `${dummyUrlRoot}/-/analytics/value_stream_analytics/stages/${stageId}`;
mock.onPut(expectedUrl).reply(200, response); mock.onPut(expectedUrl).reply(200, response);
Api.cycleAnalyticsUpdateStage(stageId, groupId, stageData) Api.cycleAnalyticsUpdateStage(stageId, groupId, stageData)
...@@ -520,7 +520,7 @@ describe('Api', () => { ...@@ -520,7 +520,7 @@ describe('Api', () => {
describe('cycleAnalyticsRemoveStage', () => { describe('cycleAnalyticsRemoveStage', () => {
it('deletes the specified data', done => { it('deletes the specified data', done => {
const response = { id: stageId, hidden: true, custom: true }; const response = { id: stageId, hidden: true, custom: true };
const expectedUrl = `${dummyUrlRoot}/-/analytics/cycle_analytics/stages/${stageId}`; const expectedUrl = `${dummyUrlRoot}/-/analytics/value_stream_analytics/stages/${stageId}`;
mock.onDelete(expectedUrl).reply(200, response); mock.onDelete(expectedUrl).reply(200, response);
Api.cycleAnalyticsRemoveStage(stageId, groupId) Api.cycleAnalyticsRemoveStage(stageId, groupId)
...@@ -541,7 +541,7 @@ describe('Api', () => { ...@@ -541,7 +541,7 @@ describe('Api', () => {
const params = { const params = {
...defaultParams, ...defaultParams,
}; };
const expectedUrl = `${dummyUrlRoot}/-/analytics/cycle_analytics/stages/thursday/duration_chart`; const expectedUrl = `${dummyUrlRoot}/-/analytics/value_stream_analytics/stages/thursday/duration_chart`;
mock.onGet(expectedUrl).reply(200, response); mock.onGet(expectedUrl).reply(200, response);
Api.cycleAnalyticsDurationChart(stageId, params) Api.cycleAnalyticsDurationChart(stageId, params)
......
...@@ -140,7 +140,7 @@ describe 'Analytics (JavaScript fixtures)', :sidekiq_inline do ...@@ -140,7 +140,7 @@ describe 'Analytics (JavaScript fixtures)', :sidekiq_inline do
end end
default_stages.each do |endpoint| default_stages.each do |endpoint|
it "cycle_analytics/events/#{endpoint}.json" do it "value_stream_analytics/events/#{endpoint}.json" do
get endpoint, params: { group_id: group, format: :json } get endpoint, params: { group_id: group, format: :json }
expect(response).to be_successful expect(response).to be_successful
...@@ -160,7 +160,7 @@ describe 'Analytics (JavaScript fixtures)', :sidekiq_inline do ...@@ -160,7 +160,7 @@ describe 'Analytics (JavaScript fixtures)', :sidekiq_inline do
sign_in(user) sign_in(user)
end end
it 'cycle_analytics/mock_data.json' do it 'value_stream_analytics/mock_data.json' do
get(:show, params: { get(:show, params: {
group_id: group.name, group_id: group.name,
cycle_analytics: { start_date: 30 } cycle_analytics: { start_date: 30 }
...@@ -194,21 +194,21 @@ describe 'Analytics (JavaScript fixtures)', :sidekiq_inline do ...@@ -194,21 +194,21 @@ describe 'Analytics (JavaScript fixtures)', :sidekiq_inline do
sign_in(user) sign_in(user)
end end
it 'analytics/cycle_analytics/stages.json' do it 'analytics/value_stream_analytics/stages.json' do
get(:index, params: { group_id: group.name }, format: :json) get(:index, params: { group_id: group.name }, format: :json)
expect(response).to be_successful expect(response).to be_successful
end end
Gitlab::Analytics::CycleAnalytics::DefaultStages.all.each do |stage| Gitlab::Analytics::CycleAnalytics::DefaultStages.all.each do |stage|
it "analytics/cycle_analytics/stages/#{stage[:name]}/records.json" do it "analytics/value_stream_analytics/stages/#{stage[:name]}/records.json" do
stage_id = group.cycle_analytics_stages.find_by(name: stage[:name]).id stage_id = group.cycle_analytics_stages.find_by(name: stage[:name]).id
get(:records, params: params.merge({ id: stage_id }), format: :json) get(:records, params: params.merge({ id: stage_id }), format: :json)
expect(response).to be_successful expect(response).to be_successful
end end
it "analytics/cycle_analytics/stages/#{stage[:name]}/median.json" do it "analytics/value_stream_analytics/stages/#{stage[:name]}/median.json" do
stage_id = group.cycle_analytics_stages.find_by(name: stage[:name]).id stage_id = group.cycle_analytics_stages.find_by(name: stage[:name]).id
get(:median, params: params.merge({ id: stage_id }), format: :json) get(:median, params: params.merge({ id: stage_id }), format: :json)
...@@ -216,13 +216,13 @@ describe 'Analytics (JavaScript fixtures)', :sidekiq_inline do ...@@ -216,13 +216,13 @@ describe 'Analytics (JavaScript fixtures)', :sidekiq_inline do
end end
end end
it "analytics/cycle_analytics/stages/label-based-stage/records.json" do it "analytics/value_stream_analytics/stages/label-based-stage/records.json" do
get(:records, params: params.merge({ id: label_based_stage.id }), format: :json) get(:records, params: params.merge({ id: label_based_stage.id }), format: :json)
expect(response).to be_successful expect(response).to be_successful
end end
it "analytics/cycle_analytics/stages/label-based-stage/median.json" do it "analytics/value_stream_analytics/stages/label-based-stage/median.json" do
get(:median, params: params.merge({ id: label_based_stage.id }), format: :json) get(:median, params: params.merge({ id: label_based_stage.id }), format: :json)
expect(response).to be_successful expect(response).to be_successful
...@@ -243,7 +243,7 @@ describe 'Analytics (JavaScript fixtures)', :sidekiq_inline do ...@@ -243,7 +243,7 @@ describe 'Analytics (JavaScript fixtures)', :sidekiq_inline do
sign_in(user) sign_in(user)
end end
it 'analytics/cycle_analytics/summary.json' do it 'analytics/value_stream_analytics/summary.json' do
get(:show, params: params, format: :json) get(:show, params: params, format: :json)
expect(response).to be_successful expect(response).to be_successful
......
# frozen_string_literal: true # frozen_string_literal: true
require 'spec_helper' require 'spec_helper'
describe 'cycle analytics events' do describe 'value stream analytics events' do
let(:user) { create(:user) } let(:user) { create(:user) }
let(:group) { create(:group)} let(:group) { create(:group)}
let(:project) { create(:project, :repository, namespace: group, public_builds: false) } let(:project) { create(:project, :repository, namespace: group, public_builds: false) }
let(:issue) { create(:issue, project: project, created_at: 2.days.ago) } let(:issue) { create(:issue, project: project, created_at: 2.days.ago) }
describe 'GET /:namespace/-/cycle_analytics/events/:stage' do describe 'GET /:namespace/-/value_stream_analytics/events/:stage' do
before do before do
stub_licensed_features(cycle_analytics_for_groups: true) stub_licensed_features(cycle_analytics_for_groups: true)
group.add_developer(user) group.add_developer(user)
......
...@@ -31,7 +31,7 @@ describe 'Analytics' do ...@@ -31,7 +31,7 @@ describe 'Analytics' do
it 'succeeds' do it 'succeeds' do
expect(Gitlab::Analytics).to receive(:cycle_analytics_enabled?).and_call_original expect(Gitlab::Analytics).to receive(:cycle_analytics_enabled?).and_call_original
expect(get('/-/analytics/cycle_analytics')).to route_to('analytics/cycle_analytics#show') expect(get('/-/analytics/value_stream_analytics')).to route_to('analytics/cycle_analytics#show')
end end
end end
......
...@@ -33,12 +33,12 @@ describe 'layouts/nav/sidebar/_analytics' do ...@@ -33,12 +33,12 @@ describe 'layouts/nav/sidebar/_analytics' do
expect(rendered).to match(/<use xlink:href=".+?icons-.+?#comment">/) expect(rendered).to match(/<use xlink:href=".+?icons-.+?#comment">/)
end end
it 'has `Cycle Analytics` link' do it 'has `Value Stream Analytics` link' do
stub_feature_flags(Gitlab::Analytics::CYCLE_ANALYTICS_FEATURE_FLAG => true) stub_feature_flags(Gitlab::Analytics::CYCLE_ANALYTICS_FEATURE_FLAG => true)
render render
expect(rendered).to have_content('Cycle Analytics') expect(rendered).to have_content('Value Stream Analytics')
expect(rendered).to include(analytics_cycle_analytics_path) expect(rendered).to include(analytics_cycle_analytics_path)
expect(rendered).to match(/<use xlink:href=".+?icons-.+?#repeat">/) expect(rendered).to match(/<use xlink:href=".+?icons-.+?#repeat">/)
end end
...@@ -84,7 +84,7 @@ describe 'layouts/nav/sidebar/_analytics' do ...@@ -84,7 +84,7 @@ describe 'layouts/nav/sidebar/_analytics' do
disable_all_analytics_feature_flags disable_all_analytics_feature_flags
expect(rendered).not_to have_content('Productivity Analytics') expect(rendered).not_to have_content('Productivity Analytics')
expect(rendered).not_to have_content('Cycle Analytics') expect(rendered).not_to have_content('Value Stream Analytics')
end end
context 'and user has access to instance statistics features' do context 'and user has access to instance statistics features' do
......
# frozen_string_literal: true # frozen_string_literal: true
# This module represents the default Cycle Analytics stages that are currently provided by CE # This module represents the default Value Stream Analytics stages that are currently provided by CE
# Each method returns a hash that can be used to build a new stage object. # Each method returns a hash that can be used to build a new stage object.
# #
# Example: # Example:
......
...@@ -50,7 +50,7 @@ module Gitlab ...@@ -50,7 +50,7 @@ module Gitlab
# Build a `SELECT` query. We find the first of the `end_time_attrs` that isn't `NULL` (call this end_time). # Build a `SELECT` query. We find the first of the `end_time_attrs` that isn't `NULL` (call this end_time).
# Next, we find the first of the start_time_attrs that isn't `NULL` (call this start_time). # Next, we find the first of the start_time_attrs that isn't `NULL` (call this start_time).
# We compute the (end_time - start_time) interval, and give it an alias based on the current # We compute the (end_time - start_time) interval, and give it an alias based on the current
# cycle analytics stage. # value stream analytics stage.
median_datetime(cte_table, interval_query(project_ids), name) median_datetime(cte_table, interval_query(project_ids), name)
end end
......
...@@ -5802,15 +5802,6 @@ msgstr "" ...@@ -5802,15 +5802,6 @@ msgstr ""
msgid "Customize your pipeline configuration." msgid "Customize your pipeline configuration."
msgstr "" msgstr ""
msgid "Cycle Analytics"
msgstr ""
msgid "Cycle Analytics can help you determine your team’s velocity"
msgstr ""
msgid "Cycle Analytics gives an overview of how much time it takes to go from idea to production in your project."
msgstr ""
msgid "CycleAnalyticsEvent|Issue closed" msgid "CycleAnalyticsEvent|Issue closed"
msgstr "" msgstr ""
...@@ -6714,15 +6705,15 @@ msgstr "" ...@@ -6714,15 +6705,15 @@ msgstr ""
msgid "Dismiss" msgid "Dismiss"
msgstr "" msgstr ""
msgid "Dismiss Cycle Analytics introduction box"
msgstr ""
msgid "Dismiss DevOps Score introduction" msgid "Dismiss DevOps Score introduction"
msgstr "" msgstr ""
msgid "Dismiss Merge Request promotion" msgid "Dismiss Merge Request promotion"
msgstr "" msgstr ""
msgid "Dismiss Value Stream Analytics introduction box"
msgstr ""
msgid "Dismiss trial promotion" msgid "Dismiss trial promotion"
msgstr "" msgstr ""
...@@ -10465,7 +10456,7 @@ msgstr "" ...@@ -10465,7 +10456,7 @@ msgstr ""
msgid "Interval Pattern" msgid "Interval Pattern"
msgstr "" msgstr ""
msgid "Introducing Cycle Analytics" msgid "Introducing Value Stream Analytics"
msgstr "" msgstr ""
msgid "Introducing Your DevOps Score" msgid "Introducing Your DevOps Score"
...@@ -13051,7 +13042,7 @@ msgstr "" ...@@ -13051,7 +13042,7 @@ msgstr ""
msgid "One or more of your personal access tokens will expire in %{days_to_expire} days or less." msgid "One or more of your personal access tokens will expire in %{days_to_expire} days or less."
msgstr "" msgstr ""
msgid "Only 'Reporter' roles and above on tiers Premium / Silver and above can see Cycle Analytics." msgid "Only 'Reporter' roles and above on tiers Premium / Silver and above can see Value Stream Analytics."
msgstr "" msgstr ""
msgid "Only Project Members" msgid "Only Project Members"
...@@ -19191,9 +19182,6 @@ msgstr "" ...@@ -19191,9 +19182,6 @@ msgstr ""
msgid "There was an error fetching configuration for charts" msgid "There was an error fetching configuration for charts"
msgstr "" msgstr ""
msgid "There was an error fetching cycle analytics stages."
msgstr ""
msgid "There was an error fetching data for the selected stage" msgid "There was an error fetching data for the selected stage"
msgstr "" msgstr ""
...@@ -19209,6 +19197,9 @@ msgstr "" ...@@ -19209,6 +19197,9 @@ msgstr ""
msgid "There was an error fetching the Designs" msgid "There was an error fetching the Designs"
msgstr "" msgstr ""
msgid "There was an error fetching value stream analytics stages."
msgstr ""
msgid "There was an error gathering the chart data" msgid "There was an error gathering the chart data"
msgstr "" msgstr ""
...@@ -19251,16 +19242,16 @@ msgstr "" ...@@ -19251,16 +19242,16 @@ msgstr ""
msgid "There was an error when unsubscribing from this label." msgid "There was an error when unsubscribing from this label."
msgstr "" msgstr ""
msgid "There was an error while fetching cycle analytics data." msgid "There was an error while fetching value stream analytics data."
msgstr "" msgstr ""
msgid "There was an error while fetching cycle analytics duration data." msgid "There was an error while fetching value stream analytics duration data."
msgstr "" msgstr ""
msgid "There was an error while fetching cycle analytics duration median data." msgid "There was an error while fetching value stream analytics duration median data."
msgstr "" msgstr ""
msgid "There was an error while fetching cycle analytics summary data." msgid "There was an error while fetching value stream analytics summary data."
msgstr "" msgstr ""
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again." msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
...@@ -21106,6 +21097,15 @@ msgstr "" ...@@ -21106,6 +21097,15 @@ msgstr ""
msgid "Value" msgid "Value"
msgstr "" msgstr ""
msgid "Value Stream Analytics"
msgstr ""
msgid "Value Stream Analytics can help you determine your team’s velocity"
msgstr ""
msgid "Value Stream Analytics gives an overview of how much time it takes to go from idea to production in your project."
msgstr ""
msgid "Variables" msgid "Variables"
msgstr "" msgstr ""
...@@ -21905,10 +21905,10 @@ msgstr "" ...@@ -21905,10 +21905,10 @@ msgstr ""
msgid "You don't have sufficient permission to perform this action." msgid "You don't have sufficient permission to perform this action."
msgstr "" msgstr ""
msgid "You don’t have access to Cycle Analytics for this group" msgid "You don’t have access to Productivity Analytics in this group"
msgstr "" msgstr ""
msgid "You don’t have access to Productivity Analytics in this group" msgid "You don’t have access to Value Stream Analytics for this group"
msgstr "" msgstr ""
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}." msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
require 'spec_helper' require 'spec_helper'
describe 'Cycle Analytics', :js do describe 'Value Stream Analytics', :js do
let(:user) { create(:user) } let(:user) { create(:user) }
let(:guest) { create(:user) } let(:guest) { create(:user) }
let(:project) { create(:project, :repository) } let(:project) { create(:project, :repository) }
...@@ -23,7 +23,7 @@ describe 'Cycle Analytics', :js do ...@@ -23,7 +23,7 @@ describe 'Cycle Analytics', :js do
end end
it 'shows introductory message' do it 'shows introductory message' do
expect(page).to have_content('Introducing Cycle Analytics') expect(page).to have_content('Introducing Value Stream Analytics')
end end
it 'shows pipeline summary' do it 'shows pipeline summary' do
...@@ -38,7 +38,7 @@ describe 'Cycle Analytics', :js do ...@@ -38,7 +38,7 @@ describe 'Cycle Analytics', :js do
end end
end end
context "when there's cycle analytics data" do context "when there's value stream analytics data" do
before do before do
allow_next_instance_of(Gitlab::ReferenceExtractor) do |instance| allow_next_instance_of(Gitlab::ReferenceExtractor) do |instance|
allow(instance).to receive(:issues).and_return([issue]) allow(instance).to receive(:issues).and_return([issue])
......
...@@ -67,8 +67,8 @@ describe 'Project navbar' do ...@@ -67,8 +67,8 @@ describe 'Project navbar' do
nav_sub_items: [ nav_sub_items: [
_('CI / CD Analytics'), _('CI / CD Analytics'),
(_('Code Review') if Gitlab.ee?), (_('Code Review') if Gitlab.ee?),
_('Cycle Analytics'), _('Repository Analytics'),
_('Repository Analytics') _('Value Stream Analytics')
] ]
}, },
{ {
......
...@@ -267,11 +267,11 @@ msgstr "Eventos de notificaciones personalizadas" ...@@ -267,11 +267,11 @@ msgstr "Eventos de notificaciones personalizadas"
msgid "Custom notification levels are the same as participating levels. With custom notification levels you will also receive notifications for select events. To find out more, check out %{notification_link}." msgid "Custom notification levels are the same as participating levels. With custom notification levels you will also receive notifications for select events. To find out more, check out %{notification_link}."
msgstr "Los niveles de notificación personalizados son los mismos que los niveles participantes. Con los niveles de notificación personalizados, también recibirá notificaciones para eventos seleccionados. Para obtener más información, consulte %{notification_link}." msgstr "Los niveles de notificación personalizados son los mismos que los niveles participantes. Con los niveles de notificación personalizados, también recibirá notificaciones para eventos seleccionados. Para obtener más información, consulte %{notification_link}."
msgid "Cycle Analytics" msgid "Value Stream Analytics"
msgstr "Cycle Analytics" msgstr "Value Stream Analytics"
msgid "Cycle Analytics gives an overview of how much time it takes to go from idea to production in your project." msgid "Value Stream Analytics gives an overview of how much time it takes to go from idea to production in your project."
msgstr "Cycle Analytics ofrece una visión general de cuánto tiempo tarda en pasar de idea a producción en su proyecto." msgstr "Value Stream Analytics ofrece una visión general de cuánto tiempo tarda en pasar de idea a producción en su proyecto."
msgid "CycleAnalyticsStage|Code" msgid "CycleAnalyticsStage|Code"
msgstr "Código" msgstr "Código"
...@@ -412,8 +412,8 @@ msgstr "Importar repositorio" ...@@ -412,8 +412,8 @@ msgstr "Importar repositorio"
msgid "Interval Pattern" msgid "Interval Pattern"
msgstr "Patrón de intervalo" msgstr "Patrón de intervalo"
msgid "Introducing Cycle Analytics" msgid "Introducing Value Stream Analytics"
msgstr "Introducción a Cycle Analytics" msgstr "Introducción a Value Stream Analytics"
msgid "Jobs for last month" msgid "Jobs for last month"
msgstr "Trabajos del mes pasado" msgstr "Trabajos del mes pasado"
......
...@@ -16,8 +16,10 @@ describe('Cycle analytics banner', () => { ...@@ -16,8 +16,10 @@ describe('Cycle analytics banner', () => {
vm.$destroy(); vm.$destroy();
}); });
it('should render cycle analytics information', () => { it('should render value stream analytics information', () => {
expect(vm.$el.querySelector('h4').textContent.trim()).toEqual('Introducing Cycle Analytics'); expect(vm.$el.querySelector('h4').textContent.trim()).toEqual(
'Introducing Value Stream Analytics',
);
expect( expect(
vm.$el vm.$el
...@@ -25,7 +27,7 @@ describe('Cycle analytics banner', () => { ...@@ -25,7 +27,7 @@ describe('Cycle analytics banner', () => {
.textContent.trim() .textContent.trim()
.replace(/[\r\n]+/g, ' '), .replace(/[\r\n]+/g, ' '),
).toContain( ).toContain(
'Cycle Analytics gives an overview of how much time it takes to go from idea to production in your project.', 'Value Stream Analytics gives an overview of how much time it takes to go from idea to production in your project.',
); );
expect(vm.$el.querySelector('a').textContent.trim()).toEqual('Read more'); expect(vm.$el.querySelector('a').textContent.trim()).toEqual('Read more');
......
...@@ -2,12 +2,12 @@ ...@@ -2,12 +2,12 @@
require 'spec_helper' require 'spec_helper'
describe 'cycle analytics events' do describe 'value stream analytics events' do
let(:user) { create(:user) } let(:user) { create(:user) }
let(:project) { create(:project, :repository, public_builds: false) } let(:project) { create(:project, :repository, public_builds: false) }
let(:issue) { create(:issue, project: project, created_at: 2.days.ago) } let(:issue) { create(:issue, project: project, created_at: 2.days.ago) }
describe 'GET /:namespace/:project/cycle_analytics/events/issues' do describe 'GET /:namespace/:project/value_stream_analytics/events/issues' do
before do before do
project.add_developer(user) project.add_developer(user)
......
...@@ -160,4 +160,31 @@ describe 'layouts/nav/sidebar/_project' do ...@@ -160,4 +160,31 @@ describe 'layouts/nav/sidebar/_project' do
end end
end end
end end
describe 'value stream analytics entry' do
let(:read_cycle_analytics) { true }
before do
allow(view).to receive(:can?).with(nil, :read_cycle_analytics, project).and_return(read_cycle_analytics)
stub_feature_flags(analytics_pages_under_project_analytics_sidebar: { enabled: false, thing: project })
end
describe 'when value stream analytics is enabled' do
it 'shows the value stream analytics entry' do
render
expect(rendered).to have_link('Value Stream Analytics', href: project_cycle_analytics_path(project))
end
end
describe 'when value stream analytics is disabled' do
let(:read_cycle_analytics) { false }
it 'does not show the value stream analytics entry' do
render
expect(rendered).not_to have_link('Value Stream Analytics', href: project_cycle_analytics_path(project))
end
end
end
end end
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