From eb5b83cf7dd2138b2da65feb9b40ee7b16b08e2e Mon Sep 17 00:00:00 2001 From: Nasser Zahrani Date: Tue, 24 Jun 2025 13:34:48 -0400 Subject: [PATCH 1/2] Cleanup usage of work_item_epic_milestones feature flag Remove usage of the work_item_epic_milestones feature flag now that Milestone widgets are available globally on epic work items. Changelog: removed --- .../groups/milestones_controller.rb | 4 ---- .../projects/milestones_controller.rb | 4 ---- app/helpers/timeboxes_helper.rb | 9 ++----- app/models/concerns/milestoneish.rb | 4 +--- app/models/group.rb | 4 ---- app/models/project.rb | 4 ---- .../shared/milestones/_issuables.html.haml | 5 ++-- .../shared/milestones/_issues_tab.html.haml | 23 ++++++------------ .../shared/milestones/_sidebar.html.haml | 19 ++++----------- app/views/shared/milestones/_tabs.html.haml | 8 ++----- .../beta/work_item_epic_milestones.yml | 10 -------- ee/app/controllers/groups/epics_controller.rb | 2 -- ee/app/models/ee/work_items/type.rb | 4 ---- .../views/shared/milestones/_weight.html.haml | 5 +--- .../projects/milestones/milestone_spec.rb | 5 ++-- .../models/concerns/ee/milestoneish_spec.rb | 24 ++++--------------- ee/spec/models/work_items/type_spec.rb | 16 ++----------- locale/gitlab.pot | 21 ---------------- .../milestones/user_creates_milestone_spec.rb | 3 +-- .../milestones/user_views_milestone_spec.rb | 14 ----------- .../projects/milestones/milestone_spec.rb | 20 +++++++--------- spec/models/concerns/milestoneish_spec.rb | 1 - 22 files changed, 38 insertions(+), 171 deletions(-) delete mode 100644 config/feature_flags/beta/work_item_epic_milestones.yml diff --git a/app/controllers/groups/milestones_controller.rb b/app/controllers/groups/milestones_controller.rb index 844405ba285d73..9855ce4986436c 100644 --- a/app/controllers/groups/milestones_controller.rb +++ b/app/controllers/groups/milestones_controller.rb @@ -6,10 +6,6 @@ class Groups::MilestonesController < Groups::ApplicationController before_action :milestone, only: [:edit, :show, :update, :issues, :merge_requests, :participants, :labels, :destroy] before_action :authorize_admin_milestones!, only: [:edit, :new, :create, :update, :destroy] - before_action do - push_force_frontend_feature_flag(:work_item_epic_milestones, !!@group.work_item_epic_milestones_feature_flag_enabled?) - end - feature_category :team_planning urgency :low diff --git a/app/controllers/projects/milestones_controller.rb b/app/controllers/projects/milestones_controller.rb index a0ffeb8734c4a2..8121502b7d302c 100644 --- a/app/controllers/projects/milestones_controller.rb +++ b/app/controllers/projects/milestones_controller.rb @@ -19,10 +19,6 @@ class Projects::MilestonesController < Projects::ApplicationController # Allow to promote milestone before_action :authorize_promote_milestone!, only: :promote - before_action do - push_force_frontend_feature_flag(:work_item_epic_milestones, !!@project&.work_item_epic_milestones_feature_flag_enabled?) - end - respond_to :html feature_category :team_planning diff --git a/app/helpers/timeboxes_helper.rb b/app/helpers/timeboxes_helper.rb index 5e5b70afc9520c..bffd4f0e15f61e 100644 --- a/app/helpers/timeboxes_helper.rb +++ b/app/helpers/timeboxes_helper.rb @@ -295,13 +295,8 @@ def milestone_issues_count_message(milestone) limit = Milestone::DISPLAY_ISSUES_LIMIT link_options = { milestone_title: @milestone.title } - if @project.work_item_epic_milestones_feature_flag_enabled? - message = _('Showing %{limit} of %{total_count} items. ') % { limit: limit, total_count: total_count } - message += link_to(_('View all'), milestones_issues_path(link_options)) - else - message = _('Showing %{limit} of %{total_count} issues. ') % { limit: limit, total_count: total_count } - message += link_to(_('View all issues'), milestones_issues_path(link_options)) - end + message = _('Showing %{limit} of %{total_count} items. ') % { limit: limit, total_count: total_count } + message += link_to(_('View all'), milestones_issues_path(link_options)) message.html_safe end diff --git a/app/models/concerns/milestoneish.rb b/app/models/concerns/milestoneish.rb index 3916cbe9bf92f7..68f18077254796 100644 --- a/app/models/concerns/milestoneish.rb +++ b/app/models/concerns/milestoneish.rb @@ -65,9 +65,7 @@ def sorted_issues(user) work_items_finder_params = issues_finder_params work_items_finder_params[:include_descendants] = true if work_items_finder_params[:include_subgroups] - container = project || group - work_items_finder_params[:issue_types] = - container.work_item_epic_milestones_feature_flag_enabled? ? %w[issue epic task] : %w[issue task] + work_items_finder_params[:issue_types] = %w[issue epic task] work_item_ids = ::WorkItems::WorkItemsFinder.new(user, work_items_finder_params) .execute.preload_associated_models diff --git a/app/models/group.rb b/app/models/group.rb index 5aa339fea8d576..991745444c02f0 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -1094,10 +1094,6 @@ def work_items_alpha_feature_flag_enabled? feature_flag_enabled_for_self_or_ancestor?(:work_items_alpha) end - def work_item_epic_milestones_feature_flag_enabled? - ::Feature.enabled?(:work_item_epic_milestones, root_ancestor, type: :beta) - end - def work_item_status_feature_available? feature_flag_enabled_for_self_or_ancestor?(:work_item_status_feature_flag, type: :wip) && licensed_feature_available?(:work_item_status) diff --git a/app/models/project.rb b/app/models/project.rb index 333bb9033429c6..e40e4545b4d601 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -3449,10 +3449,6 @@ def work_items_alpha_feature_flag_enabled? group&.work_items_alpha_feature_flag_enabled? || Feature.enabled?(:work_items_alpha) end - def work_item_epic_milestones_feature_flag_enabled? - ::Feature.enabled?(:work_item_epic_milestones, root_ancestor, type: :beta) - end - def work_item_status_feature_available? (group&.work_item_status_feature_available? || Feature.enabled?(:work_item_status_feature_flag, type: :wip)) && licensed_feature_available?(:work_item_status) diff --git a/app/views/shared/milestones/_issuables.html.haml b/app/views/shared/milestones/_issuables.html.haml index 0a03594ba25bf0..08aef3b6737582 100644 --- a/app/views/shared/milestones/_issuables.html.haml +++ b/app/views/shared/milestones/_issuables.html.haml @@ -6,9 +6,8 @@ .gl-grow-2 .gl-flex.gl-flex-col.gl-text-default = title - - if @group&.work_item_epic_milestones_feature_flag_enabled? - .gl-text-subtle.gl-text-sm - = subtitle + .gl-text-subtle.gl-text-sm + = subtitle .gl-ml-3.gl-shrink-0.gl-font-bold.gl-whitespace-nowrap.gl-text-subtle - if show_counter %span diff --git a/app/views/shared/milestones/_issues_tab.html.haml b/app/views/shared/milestones/_issues_tab.html.haml index 046bb23f761d4f..7c7897280037a8 100644 --- a/app/views/shared/milestones/_issues_tab.html.haml +++ b/app/views/shared/milestones/_issues_tab.html.haml @@ -7,19 +7,10 @@ - c.with_body do = milestone_issues_count_message(@milestone) -- if @group&.work_item_epic_milestones_feature_flag_enabled? - .row.gl-mt-3 - .col-md-4 - = render 'shared/milestones/issuables', args.merge(title: s_('Milestones|Unstarted'), subtitle: _('(open and unassigned)'), issuables: issues.opened.unassigned, id: 'unassigned', show_counter: true) - .col-md-4 - = render 'shared/milestones/issuables', args.merge(title: s_('Milestones|Ongoing'), subtitle: _('(open and unassigned)'), issuables: issues.opened.assigned, id: 'ongoing', show_counter: true) - .col-md-4 - = render 'shared/milestones/issuables', args.merge(title: s_('Milestones|Completed'), subtitle: _('(closed)'), issuables: issues.closed, id: 'closed', show_counter: true) -- else - .row.gl-mt-3 - .col-md-4 - = render 'shared/milestones/issuables', args.merge(title: s_('Milestones|Unstarted Issues (open and unassigned)'), issuables: issues.opened.unassigned, id: 'unassigned', show_counter: true) - .col-md-4 - = render 'shared/milestones/issuables', args.merge(title: s_('Milestones|Ongoing Issues (open and assigned)'), issuables: issues.opened.assigned, id: 'ongoing', show_counter: true) - .col-md-4 - = render 'shared/milestones/issuables', args.merge(title: s_('Milestones|Completed Issues (closed)'), issuables: issues.closed, id: 'closed', show_counter: true) +.row.gl-mt-3 + .col-md-4 + = render 'shared/milestones/issuables', args.merge(title: s_('Milestones|Unstarted'), subtitle: _('(open and unassigned)'), issuables: issues.opened.unassigned, id: 'unassigned', show_counter: true) + .col-md-4 + = render 'shared/milestones/issuables', args.merge(title: s_('Milestones|Ongoing'), subtitle: _('(open and unassigned)'), issuables: issues.opened.assigned, id: 'ongoing', show_counter: true) + .col-md-4 + = render 'shared/milestones/issuables', args.merge(title: s_('Milestones|Completed'), subtitle: _('(closed)'), issuables: issues.closed, id: 'closed', show_counter: true) diff --git a/app/views/shared/milestones/_sidebar.html.haml b/app/views/shared/milestones/_sidebar.html.haml index d677f29cdac8cb..a1877acc6c4677 100644 --- a/app/views/shared/milestones/_sidebar.html.haml +++ b/app/views/shared/milestones/_sidebar.html.haml @@ -1,6 +1,5 @@ - affix_offset = local_assigns.fetch(:affix_offset, "50") - project = local_assigns[:project] -- milestones_on_epics_enabled = @group&.work_item_epic_milestones_feature_flag_enabled? %aside.right-sidebar.js-right-sidebar{ data: { "auto-collapse" => true, "offset-top" => affix_offset, "spy" => "affix", "always-show-toggle" => true }, class: sidebar_gutter_collapsed_class(false), 'aria-live' => 'polite', 'aria-label': _('Milestone') } .issuable-sidebar.milestone-sidebar @@ -79,12 +78,8 @@ = sprite_icon('issues') %span= milestone.issues_visible_to_user(current_user).count .title.hide-collapsed - - if milestones_on_epics_enabled - = s_('MilestoneSidebar|Work items') - = gl_badge_tag milestone.sorted_issues(current_user).length, variant: :muted - - else - = s_('MilestoneSidebar|Issues') - = gl_badge_tag milestone.issues_visible_to_user(current_user).count, variant: :muted + = s_('MilestoneSidebar|Work items') + = gl_badge_tag milestone.sorted_issues(current_user).length, variant: :muted - if show_new_issue_link?(project) = link_to new_project_issue_path(project, issue: { milestone_id: milestone.id }), class: "gl-float-right", title: s_('MilestoneSidebar|New Issue') do = s_('MilestoneSidebar|New issue') @@ -92,17 +87,11 @@ %span.milestone-stat = link_to milestones_browse_issuables_path(milestone, type: :issues) do = s_('MilestoneSidebar|Open:') - - if milestones_on_epics_enabled - = milestone.sorted_issues(current_user).opened.length - - else - = milestone.issues_visible_to_user(current_user).opened.count + = milestone.sorted_issues(current_user).opened.length %span.milestone-stat = link_to milestones_browse_issuables_path(milestone, type: :issues, state: 'closed') do = s_('MilestoneSidebar|Closed:') - - if milestones_on_epics_enabled - = milestone.sorted_issues(current_user).closed.length - - else - = milestone.issues_visible_to_user(current_user).closed.count + = milestone.sorted_issues(current_user).closed.length .block .js-sidebar-time-tracking-root{ data: { time_estimate: @milestone.total_time_estimate, diff --git a/app/views/shared/milestones/_tabs.html.haml b/app/views/shared/milestones/_tabs.html.haml index 3fd57935a9210c..1d25b02fa308af 100644 --- a/app/views/shared/milestones/_tabs.html.haml +++ b/app/views/shared/milestones/_tabs.html.haml @@ -7,12 +7,8 @@ = sprite_icon('chevron-lg-right', size: 12) = gl_tabs_nav({ class: %w[scrolling-tabs js-milestone-tabs] }) do = gl_tab_link_to '#tab-issues', item_active: true, data: { endpoint: milestone_tab_path(milestone, 'issues', show_project_name: show_project_name) } do - - if @group&.work_item_epic_milestones_feature_flag_enabled? - = _('Work items') - = gl_tab_counter_badge milestone.sorted_issues(current_user).length - - else - = _('Issues') - = gl_tab_counter_badge milestone.issues_visible_to_user(current_user).size + = _('Work items') + = gl_tab_counter_badge milestone.sorted_issues(current_user).length - if milestone.merge_requests_enabled? = gl_tab_link_to '#tab-merge-requests', data: { endpoint: milestone_tab_path(milestone, 'merge_requests', show_project_name: show_project_name) } do = _('Merge requests') diff --git a/config/feature_flags/beta/work_item_epic_milestones.yml b/config/feature_flags/beta/work_item_epic_milestones.yml deleted file mode 100644 index 31cc1580d8b484..00000000000000 --- a/config/feature_flags/beta/work_item_epic_milestones.yml +++ /dev/null @@ -1,10 +0,0 @@ ---- -name: work_item_epic_milestones -description: Adds the milestone widget to Epic Work Items -feature_issue_url: https://gitlab.com/groups/gitlab-org/-/epics/329#note_2479555234 -introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/190104 -rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/538993 -milestone: '18.0' -group: group::product planning -type: beta -default_enabled: false diff --git a/ee/app/controllers/groups/epics_controller.rb b/ee/app/controllers/groups/epics_controller.rb index 34c311bab93236..ccf831f90a97bb 100644 --- a/ee/app/controllers/groups/epics_controller.rb +++ b/ee/app/controllers/groups/epics_controller.rb @@ -24,8 +24,6 @@ class Groups::EpicsController < Groups::ApplicationController push_force_frontend_feature_flag(:glql_integration, !!@group&.glql_integration_feature_flag_enabled?) push_force_frontend_feature_flag(:glql_load_on_click, !!@group&.glql_load_on_click_feature_flag_enabled?) push_force_frontend_feature_flag(:continue_indented_text, !!@group&.continue_indented_text_feature_flag_enabled?) - push_force_frontend_feature_flag(:work_item_epic_milestones, - !!@group.work_item_epic_milestones_feature_flag_enabled?) push_force_frontend_feature_flag(:work_items_alpha, !!group.work_items_alpha_feature_flag_enabled?) push_frontend_feature_flag(:epics_list_drawer, @group) push_frontend_feature_flag(:work_item_status_feature_flag, @group&.root_ancestor) diff --git a/ee/app/models/ee/work_items/type.rb b/ee/app/models/ee/work_items/type.rb index 393b4ce309bbe0..caa053e8bba5a8 100644 --- a/ee/app/models/ee/work_items/type.rb +++ b/ee/app/models/ee/work_items/type.rb @@ -62,10 +62,6 @@ def widgets(resource_parent) unavailable_widgets << ::WorkItems::Widgets::Assignees end - if epic? && !resource_parent.try(:work_item_epic_milestones_feature_flag_enabled?) - unavailable_widgets << ::WorkItems::Widgets::Milestone - end - unless resource_parent.root_ancestor.try(:work_item_status_feature_available?) unavailable_widgets << ::WorkItems::Widgets::Status end diff --git a/ee/app/views/shared/milestones/_weight.html.haml b/ee/app/views/shared/milestones/_weight.html.haml index 3031af1d9bd7b1..1d0f71048d3aa3 100644 --- a/ee/app/views/shared/milestones/_weight.html.haml +++ b/ee/app/views/shared/milestones/_weight.html.haml @@ -12,10 +12,7 @@ - else = _('None') .title.hide-collapsed - - if @group&.work_item_epic_milestones_feature_flag_enabled? - = _('Total weight') - - else - = _('Total issue weight') + = _('Total weight') .value.hide-collapsed{ data: { testid: 'total-issue-weight-value' } } - unless total_weight == 0 %strong.gl-font-bold= total_weight diff --git a/ee/spec/features/projects/milestones/milestone_spec.rb b/ee/spec/features/projects/milestones/milestone_spec.rb index ea125b74c29ac8..23afb264db5ddf 100644 --- a/ee/spec/features/projects/milestones/milestone_spec.rb +++ b/ee/spec/features/projects/milestones/milestone_spec.rb @@ -9,7 +9,6 @@ before do login_as(user) - stub_feature_flags(work_item_epic_milestones: false) end def visit_milestone @@ -112,7 +111,7 @@ def visit_milestone visit_milestone within '.milestone-sidebar' do - expect(page).to have_content 'Total issue weight 4' + expect(page).to have_content 'Total weight 4' end end @@ -123,7 +122,7 @@ def visit_milestone visit_milestone within '.milestone-sidebar' do - expect(page).to have_content 'Total issue weight None' + expect(page).to have_content 'Total weight None' end end end diff --git a/ee/spec/models/concerns/ee/milestoneish_spec.rb b/ee/spec/models/concerns/ee/milestoneish_spec.rb index b214972c2836e5..d92a4173f854e4 100644 --- a/ee/spec/models/concerns/ee/milestoneish_spec.rb +++ b/ee/spec/models/concerns/ee/milestoneish_spec.rb @@ -29,25 +29,11 @@ end describe '#sorted_issues' do - context 'when work_item_epic_milestones feature flag is disabled' do - before do - stub_feature_flags(work_item_epic_milestones: false) - end - - it 'excludes epic work items from return results' do - items = milestone.sorted_issues(user) - expect(items.length).to eq(1) - expect(items.first).to eq(issue) - end - end - - context 'when work_item_epic_milestones feature flag is enabled' do - it 'includes epic work items in return results' do - items = milestone.sorted_issues(user) - expect(items.first).to eq(issue) - expect(items.second).to eq(parent_group_work_item_epic) - expect(items.third).to eq(sub_group_work_item_epic) - end + it 'returns expected results' do + items = milestone.sorted_issues(user) + expect(items.first).to eq(issue) + expect(items.second).to eq(parent_group_work_item_epic) + expect(items.third).to eq(sub_group_work_item_epic) end end end diff --git a/ee/spec/models/work_items/type_spec.rb b/ee/spec/models/work_items/type_spec.rb index a383b0a96e3b5b..41f74593bd753c 100644 --- a/ee/spec/models/work_items/type_spec.rb +++ b/ee/spec/models/work_items/type_spec.rb @@ -62,20 +62,8 @@ end end - context 'when work_item_epic_milestones is enabled' do - it 'returns Milestone widget' do - expect(returned_widgets.map(&:widget_class)).to include(::WorkItems::Widgets::Milestone) - end - end - - context 'when work_item_epic_milestones is disabled' do - before do - stub_feature_flags(work_item_epic_milestones: false) - end - - it 'does not return Milestone widget' do - expect(returned_widgets.map(&:widget_class)).not_to include(::WorkItems::Widgets::Milestone) - end + it 'returns Milestone widget' do + expect(returned_widgets.map(&:widget_class)).to include(::WorkItems::Widgets::Milestone) end end diff --git a/locale/gitlab.pot b/locale/gitlab.pot index c5e8268922d9b6..90b7ae888c417f 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -39147,9 +39147,6 @@ msgstr "" msgid "MilestoneSidebar|From" msgstr "" -msgid "MilestoneSidebar|Issues" -msgstr "" - msgid "MilestoneSidebar|Merge requests" msgstr "" @@ -39204,9 +39201,6 @@ msgstr "" msgid "Milestones|Completed" msgstr "" -msgid "Milestones|Completed Issues (closed)" -msgstr "" - msgid "Milestones|Create a milestone to better track your issues and merge requests. %{learn_more_link}" msgstr "" @@ -39231,9 +39225,6 @@ msgstr "" msgid "Milestones|Ongoing" msgstr "" -msgid "Milestones|Ongoing Issues (open and assigned)" -msgstr "" - msgid "Milestones|Organize issues and merge requests into a cohesive group, and set optional start and due dates. %{learn_more_link}" msgstr "" @@ -39258,9 +39249,6 @@ msgstr "" msgid "Milestones|Unstarted" msgstr "" -msgid "Milestones|Unstarted Issues (open and unassigned)" -msgstr "" - msgid "Milestones|Use milestones to track issues and merge requests over a fixed period of time" msgstr "" @@ -58795,9 +58783,6 @@ msgid_plural "Showing %{count} projects" msgstr[0] "" msgstr[1] "" -msgid "Showing %{limit} of %{total_count} issues. " -msgstr "" - msgid "Showing %{limit} of %{total_count} items. " msgstr "" @@ -64882,9 +64867,6 @@ msgstr "" msgid "Total cores (CPUs)" msgstr "" -msgid "Total issue weight" -msgstr "" - msgid "Total memory (GB)" msgstr "" @@ -67907,9 +67889,6 @@ msgstr "" msgid "View all environments." msgstr "" -msgid "View all issues" -msgstr "" - msgid "View all personal projects" msgstr "" diff --git a/spec/features/milestones/user_creates_milestone_spec.rb b/spec/features/milestones/user_creates_milestone_spec.rb index c76ea92185cc4e..3f0ddf008a8111 100644 --- a/spec/features/milestones/user_creates_milestone_spec.rb +++ b/spec/features/milestones/user_creates_milestone_spec.rb @@ -17,7 +17,7 @@ click_button("Create milestone") expect(page).to have_content(title) - .and have_content("Issues") + .and have_content("Work items") .and have_header_with_correct_id_and_link(1, "Description header", "description-header") visit(activity_project_path(project)) @@ -35,7 +35,6 @@ before do sign_in(user) - stub_feature_flags(work_item_epic_milestones: false) visit(new_project_milestone_path(project)) end diff --git a/spec/features/milestones/user_views_milestone_spec.rb b/spec/features/milestones/user_views_milestone_spec.rb index 6d859e5ef550e3..bd08ebb7221ff2 100644 --- a/spec/features/milestones/user_views_milestone_spec.rb +++ b/spec/features/milestones/user_views_milestone_spec.rb @@ -71,20 +71,6 @@ context 'when issues on milestone are over DISPLAY_ISSUES_LIMIT' do it "limits issues to display and shows warning" do - stub_feature_flags(work_item_epic_milestones: false) - stub_const('Milestoneish::DISPLAY_ISSUES_LIMIT', 3) - - visit(project_milestone_path(project, milestone)) - - expect(page).to have_selector('#tab-issues li', count: 3) - expect(page).to have_selector('#milestone-issue-count-warning', text: 'Showing 3 of 6 issues. View all issues') - expect(page).to have_link('View all issues', href: project_issues_path(project, { milestone_title: milestone.title })) - end - end - - context 'when issues on milestone are over DISPLAY_ISSUES_LIMIT and work_item_epic_milestones FF is on' do - it "limits issues to display and shows warning" do - stub_feature_flags(work_item_epic_milestones: true) stub_const('Milestoneish::DISPLAY_ISSUES_LIMIT', 3) visit(project_milestone_path(project, milestone)) diff --git a/spec/features/projects/milestones/milestone_spec.rb b/spec/features/projects/milestones/milestone_spec.rb index 46f7f6c6d2c13b..d55ff1e96f829d 100644 --- a/spec/features/projects/milestones/milestone_spec.rb +++ b/spec/features/projects/milestones/milestone_spec.rb @@ -22,7 +22,6 @@ def sidebar_release_block_collapsed_icon before do sign_in(user) - stub_feature_flags(work_item_epic_milestones: false) end context 'when project has enabled issues' do @@ -30,17 +29,16 @@ def sidebar_release_block_collapsed_icon visit project_milestone_path(project, milestone) end - it 'shows issues tab' do + it 'shows work items tab' do within('#content-body') do - expect(page).to have_link 'Issues', href: '#tab-issues' + expect(page).to have_link 'Work items', href: '#tab-issues' expect(page).to have_selector active_tab_selector, count: 1 - expect(find(active_tab_selector)).to have_content 'Issues' - expect(page).to have_text('Unstarted Issues') + expect(find(active_tab_selector)).to have_content 'Work items' end end - it 'shows issues stats' do - expect(find('.milestone-sidebar')).to have_content 'Issues 0' + it 'shows Work item stats' do + expect(find('.milestone-sidebar')).to have_content 'Work items 0' end it 'shows link to browse and add issues' do @@ -89,15 +87,15 @@ def sidebar_release_block_collapsed_icon visit project_milestone_path(project, milestone) end - it 'does not show any issues under the issues tab' do + it 'does not show any work items under the work items tab' do within('#content-body') do - expect(find(active_tab_selector)).to have_content 'Issues' + expect(find(active_tab_selector)).to have_content 'Work items' expect(page).not_to have_selector '.issuable-row' end end - it 'hides issues stats' do - expect(find('.milestone-sidebar')).not_to have_content 'Issues 0' + it 'hides work items stats' do + expect(find('.milestone-sidebar')).not_to have_content 'Work items 0' end it 'hides new issue button' do diff --git a/spec/models/concerns/milestoneish_spec.rb b/spec/models/concerns/milestoneish_spec.rb index 8a961649272020..60dc60c54db065 100644 --- a/spec/models/concerns/milestoneish_spec.rb +++ b/spec/models/concerns/milestoneish_spec.rb @@ -28,7 +28,6 @@ before do project.add_developer(member) project.add_guest(guest) - stub_feature_flags(work_item_epic_milestones: false) end describe '#sorted_issues' do -- GitLab From 668d6e05c376694d24937e63b145932a10f1b895 Mon Sep 17 00:00:00 2001 From: Nasser Zahrani Date: Wed, 25 Jun 2025 10:51:56 -0400 Subject: [PATCH 2/2] cleanup FE references --- .../work_item_change_type_modal.vue | 10 +-- .../work_items/pages/work_items_list_app.vue | 4 +- .../burndown_chart/components/burn_charts.vue | 10 +-- .../components/burndown_chart.vue | 10 +-- .../components/burnup_chart.vue | 20 ++--- .../components/burn_charts_spec.js | 4 +- locale/gitlab.pot | 11 --- .../work_item_change_type_modal_spec.js | 5 -- .../components/work_items_list_app_spec.js | 76 +++++-------------- 9 files changed, 37 insertions(+), 113 deletions(-) diff --git a/app/assets/javascripts/work_items/components/work_item_change_type_modal.vue b/app/assets/javascripts/work_items/components/work_item_change_type_modal.vue index 7fac4e3a0f352d..1f05dc1f0cbe6e 100644 --- a/app/assets/javascripts/work_items/components/work_item_change_type_modal.vue +++ b/app/assets/javascripts/work_items/components/work_item_change_type_modal.vue @@ -162,9 +162,6 @@ export default { }); return selectOptions; }, - workItemEpicMilestonesEnabled() { - return this.glFeatures.workItemEpicMilestones; - }, isSelectedWorkItemTypeEpic() { return this.selectedWorkItemType?.name === WORK_ITEM_TYPE_NAME_EPIC; }, @@ -227,11 +224,7 @@ export default { widgetsWithExistingData() { return this.widgetsWithExistingDataList.reduce((widgets, item) => { // Skip adding milestone to widget difference if upgrading to epic - if ( - this.workItemEpicMilestonesEnabled && - this.isSelectedWorkItemTypeEpic && - item.type === WIDGET_TYPE_MILESTONE - ) { + if (this.isSelectedWorkItemTypeEpic && item.type === WIDGET_TYPE_MILESTONE) { return widgets; } widgets.push({ @@ -244,7 +237,6 @@ export default { noValuePresentWidgets() { return this.widgetsWithExistingDataList.reduce((acc, item) => { if ( - this.workItemEpicMilestonesEnabled && this.isSelectedWorkItemTypeEpic && this.milestoneWidget?.projectMilestone && item.type === WIDGET_TYPE_MILESTONE diff --git a/app/assets/javascripts/work_items/pages/work_items_list_app.vue b/app/assets/javascripts/work_items/pages/work_items_list_app.vue index 4e8e69c622f4b0..7eec390fce29f5 100644 --- a/app/assets/javascripts/work_items/pages/work_items_list_app.vue +++ b/app/assets/javascripts/work_items/pages/work_items_list_app.vue @@ -592,9 +592,7 @@ export default { hasManualSort: false, hasStartDate: true, hasPriority: !this.isEpicsList, - hasMilestoneDueDate: Boolean( - !this.isEpicsList || (this.isEpicsList && this.glFeatures.workItemEpicMilestones), - ), + hasMilestoneDueDate: true, hasLabelPriority: !this.isEpicsList, hasWeight: !this.isEpicsList, }); diff --git a/ee/app/assets/javascripts/burndown_chart/components/burn_charts.vue b/ee/app/assets/javascripts/burndown_chart/components/burn_charts.vue index 3d88f3dea89800..a83a0e4f74908b 100644 --- a/ee/app/assets/javascripts/burndown_chart/components/burn_charts.vue +++ b/ee/app/assets/javascripts/burndown_chart/components/burn_charts.vue @@ -186,21 +186,15 @@ export default { return this.issuesSelected ? FILTER_BY_ISSUES : FILTER_BY_ISSUE_WEIGHT; }, filterByOptions() { - const countFilterText = this.glFeatures.workItemEpicMilestones - ? __('Count') - : __('Issue count'); - const weightFilterText = this.glFeatures.workItemEpicMilestones - ? __('Weight') - : __('Issue weight'); return [ { value: FILTER_BY_ISSUES, - text: countFilterText, + text: __('Count'), props: { 'data-testid': 'issue-button' }, }, { value: FILTER_BY_ISSUE_WEIGHT, - text: weightFilterText, + text: __('Weight'), props: { 'data-testid': 'weight-button' }, }, ]; diff --git a/ee/app/assets/javascripts/burndown_chart/components/burndown_chart.vue b/ee/app/assets/javascripts/burndown_chart/components/burndown_chart.vue index 0cf37148d65180..8643f030495838 100644 --- a/ee/app/assets/javascripts/burndown_chart/components/burndown_chart.vue +++ b/ee/app/assets/javascripts/burndown_chart/components/burndown_chart.vue @@ -3,14 +3,12 @@ import { GlLineChart } from '@gitlab/ui/dist/charts'; import { merge } from 'lodash'; import dateFormat from '~/lib/dateformat'; import { __, n__, s__, sprintf } from '~/locale'; -import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import commonChartOptions from './common_chart_options'; export default { components: { GlLineChart, }, - mixins: [glFeatureFlagMixin()], props: { startDate: { type: String, @@ -94,7 +92,7 @@ export default { return series; }, yAxisTitle() { - return this.glFeatures.workItemEpicMilestones ? __('Work items') : __('Issues'); + return __('Work items'); }, options() { return merge({}, commonChartOptions, { @@ -122,12 +120,8 @@ export default { if (this.issuesSelected) { this.tooltip.content = n__('%d remaining', '%d remaining', seriesData.value[1]); - } else if (this.glFeatures.workItemEpicMilestones) { - this.tooltip.content = sprintf(__('%{total} remaining weight'), { - total: seriesData.value[1], - }); } else { - this.tooltip.content = sprintf(__('%{total} remaining issue weight'), { + this.tooltip.content = sprintf(__('%{total} remaining weight'), { total: seriesData.value[1], }); } diff --git a/ee/app/assets/javascripts/burndown_chart/components/burnup_chart.vue b/ee/app/assets/javascripts/burndown_chart/components/burnup_chart.vue index 4aeaadb0e71ec9..a7993bf44f8727 100644 --- a/ee/app/assets/javascripts/burndown_chart/components/burnup_chart.vue +++ b/ee/app/assets/javascripts/burndown_chart/components/burnup_chart.vue @@ -2,15 +2,13 @@ import { GlLineChart } from '@gitlab/ui/dist/charts'; import { merge } from 'lodash'; import dateFormat from '~/lib/dateformat'; -import { __, n__, sprintf } from '~/locale'; -import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; +import { __, sprintf } from '~/locale'; import commonChartOptions from './common_chart_options'; export default { components: { GlLineChart, }, - mixins: [glFeatureFlagMixin()], props: { startDate: { type: String, @@ -72,7 +70,7 @@ export default { return series; }, yAxisTitle() { - return this.glFeatures.workItemEpicMilestones ? __('Work items') : __('Issues'); + return __('Work items'); }, options() { return merge({}, commonChartOptions, { @@ -106,17 +104,15 @@ export default { const count = total.value[1]; const completedCount = completed.value[1]; - let totalText = n__('%d issue', '%d issues', count); - let completedText = n__('%d completed issue', '%d completed issues', completedCount); + let totalText; + let completedText; - if (!this.issuesSelected) { - totalText = sprintf(__('%{count} total weight'), { count }); - completedText = sprintf(__('%{completedCount} completed weight'), { completedCount }); - } - - if (this.glFeatures.workItemEpicMilestones) { + if (this.issuesSelected) { totalText = sprintf(__('%{count} total'), { count }); completedText = sprintf(__('%{completedCount} completed'), { completedCount }); + } else { + totalText = sprintf(__('%{count} total weight'), { count }); + completedText = sprintf(__('%{completedCount} completed weight'), { completedCount }); } this.tooltip.total = totalText; diff --git a/ee/spec/frontend/burndown_chart/components/burn_charts_spec.js b/ee/spec/frontend/burndown_chart/components/burn_charts_spec.js index 854f28d55e3c96..85c0325468f71e 100644 --- a/ee/spec/frontend/burndown_chart/components/burn_charts_spec.js +++ b/ee/spec/frontend/burndown_chart/components/burn_charts_spec.js @@ -108,8 +108,8 @@ describe('burndown_chart', () => { createComponent(); expect(findFilterByControl().props('options')).toEqual([ - { value: 'issues', text: 'Issue count', props: { 'data-testid': 'issue-button' } }, - { value: 'issue_weight', text: 'Issue weight', props: { 'data-testid': 'weight-button' } }, + { value: 'issues', text: 'Count', props: { 'data-testid': 'issue-button' } }, + { value: 'issue_weight', text: 'Weight', props: { 'data-testid': 'weight-button' } }, ]); }); diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 90b7ae888c417f..fccf926d436499 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -251,11 +251,6 @@ msgid_plural "%d commits," msgstr[0] "" msgstr[1] "" -msgid "%d completed issue" -msgid_plural "%d completed issues" -msgstr[0] "" -msgstr[1] "" - msgid "%d contact" msgid_plural "%d contacts" msgstr[0] "" @@ -1605,9 +1600,6 @@ msgstr "" msgid "%{total}" msgstr "" -msgid "%{total} remaining issue weight" -msgstr "" - msgid "%{total} remaining weight" msgstr "" @@ -33966,9 +33958,6 @@ msgstr "" msgid "Issue cannot be found." msgstr "" -msgid "Issue count" -msgstr "" - msgid "Issue created from vulnerability %{vulnerability_link}" msgstr "" diff --git a/spec/frontend/work_items/components/work_item_change_type_modal_spec.js b/spec/frontend/work_items/components/work_item_change_type_modal_spec.js index 5c2fb7e2ab9eef..586a1e6b961ef9 100644 --- a/spec/frontend/work_items/components/work_item_change_type_modal_spec.js +++ b/spec/frontend/work_items/components/work_item_change_type_modal_spec.js @@ -73,7 +73,6 @@ describe('WorkItemChangeTypeModal component', () => { const createComponent = ({ hasParent = false, hasChildren = false, - workItemEpicMilestones = false, widgets = [], workItemType = WORK_ITEM_TYPE_NAME_TASK, convertWorkItemMutationHandler = convertWorkItemMutationSuccessHandler, @@ -99,9 +98,6 @@ describe('WorkItemChangeTypeModal component', () => { allowedConversionTypesEE, }, provide: { - glFeatures: { - workItemEpicMilestones, - }, hasSubepicsFeature, }, stubs: { @@ -232,7 +228,6 @@ describe('WorkItemChangeTypeModal component', () => { createComponent({ workItemType: WORK_ITEM_TYPE_NAME_ISSUE, widgets: [workItemChangeTypeWidgets.MILESTONE], - workItemEpicMilestones: true, allowedConversionTypesEE, }); diff --git a/spec/frontend/work_items/list/components/work_items_list_app_spec.js b/spec/frontend/work_items/list/components/work_items_list_app_spec.js index ff6e833fdaced6..8f833e51d52b73 100644 --- a/spec/frontend/work_items/list/components/work_items_list_app_spec.js +++ b/spec/frontend/work_items/list/components/work_items_list_app_spec.js @@ -317,63 +317,29 @@ describeSkipVue3(skipReason, () => { }); describe('when epics list', () => { - describe('when workItemEpicMilestones is disabled', () => { - it('does not render "Priority", "Milestone due date", "Label priority", and "Weight" sort options', async () => { - mountComponent({ - provide: { - glFeatures: { - workItemEpicMilestones: false, - }, - hasBlockedIssuesFeature: true, - hasIssuableHealthStatusFeature: true, - hasIssueWeightsFeature: true, - workItemType: WORK_ITEM_TYPE_NAME_EPIC, - }, - }); - await waitForPromises(); - - expect(findIssuableList().props('sortOptions')).toEqual([ - expect.objectContaining({ title: 'Created date' }), - expect.objectContaining({ title: 'Updated date' }), - expect.objectContaining({ title: 'Closed date' }), - expect.objectContaining({ title: 'Due date' }), - expect.objectContaining({ title: 'Popularity' }), - expect.objectContaining({ title: 'Title' }), - expect.objectContaining({ title: 'Start date' }), - expect.objectContaining({ title: 'Health' }), - expect.objectContaining({ title: 'Blocking' }), - ]); + it('does not render "Priority", "Label priority", and "Weight" sort options', async () => { + mountComponent({ + provide: { + hasBlockedIssuesFeature: true, + hasIssuableHealthStatusFeature: true, + hasIssueWeightsFeature: true, + workItemType: WORK_ITEM_TYPE_NAME_EPIC, + }, }); - }); - - describe('when workItemEpicMilestones is enabled', () => { - it('does not render "Priority", "Label priority", and "Weight" sort options', async () => { - mountComponent({ - provide: { - glFeatures: { - workItemEpicMilestones: true, - }, - hasBlockedIssuesFeature: true, - hasIssuableHealthStatusFeature: true, - hasIssueWeightsFeature: true, - workItemType: WORK_ITEM_TYPE_NAME_EPIC, - }, - }); - await waitForPromises(); + await waitForPromises(); - expect(findIssuableList().props('sortOptions')).toEqual([ - expect.objectContaining({ title: 'Created date' }), - expect.objectContaining({ title: 'Updated date' }), - expect.objectContaining({ title: 'Closed date' }), - expect.objectContaining({ title: 'Milestone due date' }), - expect.objectContaining({ title: 'Due date' }), - expect.objectContaining({ title: 'Popularity' }), - expect.objectContaining({ title: 'Title' }), - expect.objectContaining({ title: 'Start date' }), - expect.objectContaining({ title: 'Health' }), - expect.objectContaining({ title: 'Blocking' }), - ]); - }); + expect(findIssuableList().props('sortOptions')).toEqual([ + expect.objectContaining({ title: 'Created date' }), + expect.objectContaining({ title: 'Updated date' }), + expect.objectContaining({ title: 'Closed date' }), + expect.objectContaining({ title: 'Milestone due date' }), + expect.objectContaining({ title: 'Due date' }), + expect.objectContaining({ title: 'Popularity' }), + expect.objectContaining({ title: 'Title' }), + expect.objectContaining({ title: 'Start date' }), + expect.objectContaining({ title: 'Health' }), + expect.objectContaining({ title: 'Blocking' }), + ]); }); }); }); -- GitLab