Commit 3c2bc9a8 authored by Kushal Pandya's avatar Kushal Pandya

Merge branch '13569-remove-cookie-flag-after-cycle-analytics-refactor' into 'master'

Remove cookie flag after cycle analytics refactor

Closes #13569

See merge request gitlab-org/gitlab!17341
parents c73dc99d e2d48b16
......@@ -131,7 +131,7 @@ export default {
>
<label class="text-bold mb-0 mr-1">{{ __('Timeframe') }}</label>
<date-range-dropdown
class="js-timeframe-dropdown"
class="js-timeframe-filter"
:available-days-in-past="dateOptions"
:default-selected="dataTimeframe"
@selected="onTimeframeSelect"
......
import initCycleAnalytics from '~/cycle_analytics/cycle_analytics_bundle';
import initCycleAnalyticsApp from 'ee/analytics/cycle_analytics/index';
import { parseBoolean } from '~/lib/utils/common_utils';
import Cookies from 'js-cookie';
if (parseBoolean(Cookies.get('cycle_analytics_app'))) {
document.addEventListener('DOMContentLoaded', initCycleAnalyticsApp);
} else {
document.addEventListener('DOMContentLoaded', initCycleAnalytics);
}
document.addEventListener('DOMContentLoaded', initCycleAnalyticsApp);
- page_title _("Cycle Analytics")
- customizable_cycle_analytics = Feature.enabled?(:customizable_cycle_analytics)
- if cookies[:cycle_analytics_app] == 'true'
#js-cycle-analytics-app{ data: { "empty-state-svg-path" => image_path("illustrations/analytics/cycle-analytics-empty-chart.svg"), "no-data-svg-path" => image_path("illustrations/analytics/cycle-analytics-empty-chart.svg"), "no-access-svg-path" => image_path("illustrations/analytics/no-access.svg") } }
- else
.page-title-holder.d-flex.align-items-center
%h1.page-title
= page_title
#cycle-analytics.m-0.mw-100
.mt-3.py-2.px-3.d-flex.bg-gray-light.border-top.border-bottom.flex-column.flex-md-row.justify-content-between
%groups-dropdown-filter.dropdown-select{ "@selected" => "setSelectedGroup" }
%projects-dropdown-filter.ml-md-1.mt-1.mt-md-0.dropdown-select{ "v-if" => "selectedGroup",
":group-id" => "selectedGroup.id",
":key" => "selectedGroup.id",
"@selected" => "setSelectedProjects",
":multi-select" => 'multiProjectSelect' } }
.ml-0.ml-md-auto.mt-2.mt-md-0.d-flex.flex-column.flex-md-row.align-items-md-center.justify-content-md-end{ "v-if" => "selectedGroup" }
%label.text-bold.mb-0.mr-1
{{ __('Timeframe') }}
%date-range-dropdown.js-timeframe-filter{ "@selected" => "setSelectedDate",
":available-days-in-past" => "dateOptions",
":default-selected" => "startDate" }
%gl-empty-state{ "v-show" => "!selectedGroup",
"title" => _("Cycle Analytics can help you determine your team’s velocity"),
"svg-path" => image_path("illustrations/analytics/cycle-analytics-empty-chart.svg"),
"description" => _("Start by choosing a group to see how your team is spending time. You can then drill down to the project level.") }
.js-cycle-analytics{ "v-show" => "selectedGroup" }
.wrapper.mt-3
.card
.card-header.font-weight-bold
{{ __('Recent Activity') }}
.content-block
.container-fluid
.row
.col-sm-2
.col-sm-4.col-12.column{ "v-for" => "item in state.summary" }
%h3.header {{ item.value }}
%p.text {{ item.title }}
.stage-panel-container
.card.stage-panel
.card-header.border-bottom-0
%nav.col-headers
%ul
%li.stage-header.pl-5
%span.stage-name.font-weight-bold
{{ s__('ProjectLifecycle|Stage') }}
%i.has-tooltip.fa.fa-question-circle{ "data-placement" => "top", title: _("The phase of the development lifecycle."), "aria-hidden" => "true" }
%li.median-header
%span.stage-name.font-weight-bold
{{ __('Median') }}
%i.has-tooltip.fa.fa-question-circle{ "data-placement" => "top", title: _("The value lying at the midpoint of a series of observed values. E.g., between 3, 5, 9, the median is 5. Between 3, 5, 7, 8, the median is (5+7)/2 = 6."), "aria-hidden" => "true" }
%li.event-header.pl-3
%span.stage-name.font-weight-bold
{{ currentStage ? __(currentStage.legend) : __('Related Issues') }}
%i.has-tooltip.fa.fa-question-circle{ "data-placement" => "top", title: _("The collection of events added to the data gathered for that stage."), "aria-hidden" => "true" }
%li.total-time-header.pr-5.text-right
%span.stage-name.font-weight-bold
{{ __('Total Time') }}
%i.has-tooltip.fa.fa-question-circle{ "data-placement" => "top", title: _("The time taken by each data entry gathered by that stage."), "aria-hidden" => "true" }
.stage-panel-body
%nav.stage-nav
%ul
%stage-nav-item{ "v-for" => "stage in state.stages", ":key" => '`ca-stage-title-${stage.title}`', '@select' => 'selectStage(stage)', ":title" => "stage.title", ":is-user-allowed" => "stage.isUserAllowed", ":value" => "stage.value", ":is-active" => "stage.active" }
- if customizable_cycle_analytics
%add-stage-button{ '@showform' => 'showAddStageForm', ":active" => 'isCustomStageForm' }
.section.stage-events
%template{ "v-if" => "isLoadingStage" }
= icon("spinner spin")
%template{ "v-if" => "currentStage && !currentStage.isUserAllowed" }
= render partial: "projects/cycle_analytics/no_access"
%template{ "v-else" => true }
%template{ "v-if" => "isEmptyStage && !isLoadingStage && !isCustomStageForm" }
= render partial: "projects/cycle_analytics/empty_stage"
%template{ "v-if" => "state.events.length && !isLoadingStage && !isEmptyStage && !isCustomStageForm" }
%component{ ":is" => "currentStage.component", ":stage" => "currentStage", ":items" => "state.events" }
- if customizable_cycle_analytics
%custom-stage-form-container{ "v-if" => "isCustomStageForm && selectedGroup && selectedGroup.full_path", ":namespace" => "selectedGroup.full_path" }
#js-cycle-analytics-app{ data: { "empty-state-svg-path" => image_path("illustrations/analytics/cycle-analytics-empty-chart.svg"), "no-data-svg-path" => image_path("illustrations/analytics/cycle-analytics-empty-chart.svg"), "no-access-svg-path" => image_path("illustrations/analytics/no-access.svg") } }
......@@ -49,11 +49,6 @@ describe 'Group Cycle Analytics', :js do
it 'shows the date filter' do
expect(page).to have_selector('.js-timeframe-filter', visible: true)
end
it 'smoke test' do
expect(page).not_to have_selector('.cycle-analytics', visible: true)
expect(page).to have_selector('#cycle-analytics', visible: true)
end
end
# TODO: Followup should have tests for stub_licensed_features(cycle_analytics_for_groups: false)
......@@ -72,162 +67,142 @@ describe 'Group Cycle Analytics', :js do
dropdown.click
end
context 'with cycle_analytics_app cookie set', :js do
before do
set_cookie('cycle_analytics_app', 'true')
group.add_owner(user)
project.add_maintainer(user)
sign_in(user)
visit analytics_cycle_analytics_path
it 'displays empty text' do
[
'Cycle 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.'
].each do |content|
expect(page).to have_content(content)
end
end
it 'displays empty text' do
[
'Cycle 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.'
].each do |content|
expect(page).to have_content(content)
end
context 'with a group selected' do
before do
select_group
end
context 'with a group selected' do
before do
select_group
end
it 'smoke test' do
expect(page).to have_selector('.cycle-analytics', visible: true)
expect(page).not_to have_selector('#cycle-analytics', visible: true)
end
context 'summary table', :js do
it 'will display recent activity' do
page.within(find('.js-summary-table')) do
expect(page).to have_selector('.card-header')
expect(page).to have_content('Recent Activity')
end
context 'summary table', :js do
it 'will display recent activity' do
page.within(find('.js-summary-table')) do
expect(page).to have_selector('.card-header')
expect(page).to have_content('Recent Activity')
end
end
it 'displays the number of issues' do
expect(page).to have_content('New Issues')
it 'displays the number of issues' do
expect(page).to have_content('New Issues')
issue_count = find(".card .header", match: :first)
expect(issue_count).to have_content('3')
end
issue_count = find(".card .header", match: :first)
expect(issue_count).to have_content('3')
end
it 'displays the number of deploys' do
expect(page).to have_content('Deploys')
it 'displays the number of deploys' do
expect(page).to have_content('Deploys')
deploys_count = page.all(".card .header").last
expect(deploys_count).to have_content('-')
end
deploys_count = page.all(".card .header").last
expect(deploys_count).to have_content('-')
end
end
# These should probably move to more unit / integration type tests
# should have a group set and some data
context 'stage panel' do
it 'displays the stage table headers' do
expect(page).to have_selector('.stage-header', visible: true)
expect(page).to have_selector('.median-header', visible: true)
expect(page).to have_selector('.event-header', visible: true)
expect(page).to have_selector('.total-time-header', visible: true)
end
context 'stage panel' do
it 'displays the stage table headers' do
expect(page).to have_selector('.stage-header', visible: true)
expect(page).to have_selector('.median-header', visible: true)
expect(page).to have_selector('.event-header', visible: true)
expect(page).to have_selector('.total-time-header', visible: true)
end
end
context 'stage nav' do
it 'displays the list of stages' do
expect(page).to have_selector('.stage-nav', visible: true)
end
context 'stage nav' do
it 'displays the list of stages' do
expect(page).to have_selector('.stage-nav', visible: true)
end
it 'displays the default list of stages' do
stage_nav = page.find('.stage-nav')
it 'displays the default list of stages' do
stage_nav = page.find('.stage-nav')
%w[Issue Plan Code Test Review Staging Production].each do |item|
expect(stage_nav).to have_content(item)
end
%w[Issue Plan Code Test Review Staging Production].each do |item|
expect(stage_nav).to have_content(item)
end
end
end
end
def select_stage(name)
page.find('.stage-nav .stage-nav-item .stage-name', text: name, match: :prefer_exact).click
def select_stage(name)
page.find('.stage-nav .stage-nav-item .stage-name', text: name, match: :prefer_exact).click
wait_for_requests
end
wait_for_requests
end
def create_merge_request(id, extra_params = {})
params = {
id: id,
target_branch: 'master',
source_project: project2,
source_branch: "feature-branch-#{id}",
title: "mr name#{id}",
created_at: 2.days.ago
}.merge(extra_params)
create(:merge_request, params)
end
def create_merge_request(id, extra_params = {})
params = {
id: id,
target_branch: 'master',
source_project: project2,
source_branch: "feature-branch-#{id}",
title: "mr name#{id}",
created_at: 2.days.ago
}.merge(extra_params)
create(:merge_request, params)
end
context 'with lots of data', :js do
let!(:issue) { create(:issue, project: project, created_at: 5.days.ago) }
context 'with lots of data', :js do
let!(:issue) { create(:issue, project: project, created_at: 5.days.ago) }
before do
create_cycle(user, project, issue, mr, milestone, pipeline)
before do
create_cycle(user, project, issue, mr, milestone, pipeline)
deploy_master(user, project, environment: 'staging')
deploy_master(user, project)
deploy_master(user, project, environment: 'staging')
deploy_master(user, project)
select_group
end
select_group
end
dummy_stages = [
{ title: "Issue", description: "Time before an issue gets scheduled", events_count: 1, median: "5 days" },
{ title: "Plan", description: "Time before an issue starts implementation", events_count: 1, median: "Not enough data" },
{ title: "Code", description: "Time until first merge request", events_count: 1, median: "less than a minute" },
{ title: "Test", description: "Total test time for all commits/merges", events_count: 1, median: "Not enough data" },
{ title: "Review", description: "Time between merge request creation and merge/close", events_count: 1, median: "less than a minute" },
{ title: "Staging", description: "From merge request merge until deploy to production", events_count: 1, median: "less than a minute" },
{ title: "Production", description: "From issue creation until deploy to production", events_count: 1, median: "5 days" }
]
it 'each stage will have median values' do
stages = page.all(".stage-nav .stage-median").collect(&:text)
stages.each_with_index do |median, index|
expect(median).to eq(dummy_stages[index][:median])
end
dummy_stages = [
{ title: "Issue", description: "Time before an issue gets scheduled", events_count: 1, median: "5 days" },
{ title: "Plan", description: "Time before an issue starts implementation", events_count: 1, median: "Not enough data" },
{ title: "Code", description: "Time until first merge request", events_count: 1, median: "less than a minute" },
{ title: "Test", description: "Total test time for all commits/merges", events_count: 1, median: "Not enough data" },
{ title: "Review", description: "Time between merge request creation and merge/close", events_count: 1, median: "less than a minute" },
{ title: "Staging", description: "From merge request merge until deploy to production", events_count: 1, median: "less than a minute" },
{ title: "Production", description: "From issue creation until deploy to production", events_count: 1, median: "5 days" }
]
it 'each stage will have median values' do
stages = page.all(".stage-nav .stage-median").collect(&:text)
stages.each_with_index do |median, index|
expect(median).to eq(dummy_stages[index][:median])
end
end
it 'each stage will display the events description when selected' do
dummy_stages.each do |stage|
select_stage(stage[:title])
it 'each stage will display the events description when selected' do
dummy_stages.each do |stage|
select_stage(stage[:title])
expect(page.find('.stage-events .events-description').text).to have_text(stage[:description])
end
expect(page.find('.stage-events .events-description').text).to have_text(stage[:description])
end
end
it 'each stage with events will display the stage events list when selected' do
dummy_stages.each do |stage|
select_stage(stage[:title])
it 'each stage with events will display the stage events list when selected' do
dummy_stages.each do |stage|
select_stage(stage[:title])
if stage[:events_count] == 0
expect(page).not_to have_selector('.stage-events .stage-event-item')
else
expect(page).to have_selector('.stage-events .stage-event-list')
expect(page.all('.stage-events .stage-event-item').length).to eq(stage[:events_count])
end
if stage[:events_count] == 0
expect(page).not_to have_selector('.stage-events .stage-event-item')
else
expect(page).to have_selector('.stage-events .stage-event-list')
expect(page.all('.stage-events .stage-event-item').length).to eq(stage[:events_count])
end
end
end
it 'each stage will be selectable' do
dummy_stages.each do |stage|
select_stage(stage[:title])
it 'each stage will be selectable' do
dummy_stages.each do |stage|
select_stage(stage[:title])
expect(page.find('.stage-nav .active .stage-name').text).to eq(stage[:title])
end
expect(page.find('.stage-nav .active .stage-name').text).to eq(stage[:title])
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