diff --git a/modules/backlogs/app/controllers/projects/settings/backlogs_controller.rb b/modules/backlogs/app/controllers/projects/settings/backlogs_controller.rb index b53f8be524b8..a59b335f0557 100644 --- a/modules/backlogs/app/controllers/projects/settings/backlogs_controller.rb +++ b/modules/backlogs/app/controllers/projects/settings/backlogs_controller.rb @@ -31,17 +31,10 @@ class Projects::Settings::BacklogsController < Projects::SettingsController menu_item :settings_backlogs - def show - @statuses_done_for_project = @project.done_statuses.pluck(:id) - end + def show; end def update - selected_statuses = (params[:statuses] || []).filter_map do |work_package_status| - Status.find(work_package_status[:status_id].to_i) - end - - @project.done_statuses = selected_statuses - @project.save! + @project.update!(params.expect(project: { done_status_ids: [] })) flash[:notice] = I18n.t(:notice_successful_update) diff --git a/modules/backlogs/spec/features/resolved_status_spec.rb b/modules/backlogs/app/forms/projects/settings/backlogs_settings_form.rb similarity index 54% rename from modules/backlogs/spec/features/resolved_status_spec.rb rename to modules/backlogs/app/forms/projects/settings/backlogs_settings_form.rb index e2dd860eff3b..316380b75292 100644 --- a/modules/backlogs/spec/features/resolved_status_spec.rb +++ b/modules/backlogs/app/forms/projects/settings/backlogs_settings_form.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + #-- copyright # OpenProject is an open source project management software. # Copyright (C) the OpenProject GmbH @@ -26,38 +28,43 @@ # See COPYRIGHT and LICENSE files for more details. #++ -require "spec_helper" -require_relative "../support/pages/projects/settings/backlogs" - -RSpec.describe "Resolved status" do - let!(:project) do - create(:project, - enabled_module_names: %w(backlogs)) - end - let!(:status) { create(:status, is_default: true) } - let(:role) do - create(:project_role, - permissions: %i[select_done_statuses view_sprints]) - end - let!(:current_user) do - create(:user, - member_with_roles: { project => role }) - end - let(:settings_page) { Pages::Projects::Settings::Backlogs.new(project) } - - before do - login_as current_user - end +module Projects + module Settings + class BacklogsSettingsForm < ApplicationForm + form do |f| + f.autocompleter( + name: :done_status_ids, + label: I18n.t(:"backlogs.definition_of_done"), + caption: I18n.t(:"backlogs.definition_of_done_caption"), + autocomplete_options: { + multiple: true, + closeOnSelect: false, + clearable: false, + decorated: true, + data: { + test_selector: "done_status_ids_autocomplete" + } + } + ) do |list| + available_statuses.each do |label, value| + active = value.in?(model.done_status_ids) - it "allows setting a status as done although it is not closed" do - settings_page.visit! + list.option( + label:, + value:, + selected: active + ) + end + end - check status.name - click_button "Save" + f.submit(scheme: :primary, name: :apply, label: I18n.t(:button_save)) + end - expect_flash(type: :success, message: "Successful update") + private - expect(page) - .to have_checked_field(status.name) + def available_statuses + Status.pluck(:name, :id) + end + end end end diff --git a/modules/backlogs/app/views/projects/settings/backlogs/show.html.erb b/modules/backlogs/app/views/projects/settings/backlogs/show.html.erb index bb32c332dbf0..11ac6fb8e620 100644 --- a/modules/backlogs/app/views/projects/settings/backlogs/show.html.erb +++ b/modules/backlogs/app/views/projects/settings/backlogs/show.html.erb @@ -29,75 +29,39 @@ See COPYRIGHT and LICENSE files for more details. <%= render Primer::OpenProject::PageHeader.new do |header| - header.with_title { t("backlogs.definition_of_done") } + header.with_title { t(:label_backlogs) } + header.with_breadcrumbs( [{ href: project_overview_path(@project), text: @project.name }, { href: project_settings_general_path(@project), text: I18n.t(:label_project_settings) }, - t("backlogs.definition_of_done")] + t(:label_backlogs)] ) + + header.with_action_menu( + menu_arguments: { anchor_align: :end }, + button_arguments: { + icon: :"kebab-horizontal", + "aria-label": t(:label_more) + } + ) do |menu| + menu.with_item( + tag: :button, + href: rebuild_positions_project_settings_backlogs_path(@project), + label: t(:"backlogs.rebuild_positions"), + form_arguments: { method: :post } + ) do |item| + item.with_leading_visual_icon(icon: :sync) + end + end end %> -<%= styled_form_tag( - project_settings_backlogs_path(@project), - method: :patch, - id: "edit_project_#{@project.id}" - ) do %> - -
|
-
-
-
-
- <%= Status.model_name.human %>
-
-
- |
-
-
-
-
-
- <%= t("backlogs.work_package_is_closed") %>
-
-
- |
-
|---|---|
| - <%= status.name %> - | -- <% checkbox_id = status.name.parameterize.underscore %> - <%= styled_label_tag checkbox_id, t("backlogs.label_is_done_status", status_name: status.name), class: "sr-only" %> - <%= (styled_check_box_tag "statuses[][status_id]", status.id.to_s, @statuses_done_for_project.include?(status.id), id: checkbox_id) %> - | -
<%= styled_button_tag t("backlogs.rebuild"), class: "-primary" %>
+<%= + settings_primer_form_with( + url: project_settings_backlogs_path(@project), + model: @project, + method: :patch + ) do |f| +%> + <%= render Projects::Settings::BacklogsSettingsForm.new(f) %> <% end %> diff --git a/modules/backlogs/config/locales/en.yml b/modules/backlogs/config/locales/en.yml index 9e58970b397f..3d26e7049272 100644 --- a/modules/backlogs/config/locales/en.yml +++ b/modules/backlogs/config/locales/en.yml @@ -69,6 +69,7 @@ en: any: "any" column_width: "Column width" definition_of_done: "Definition of Done" + definition_of_done_caption: "Work packages with these statuses are treated as completed in backlog views and reporting." impediment: "Impediment" label_versions_default_fold_state: "Show versions folded" caption_versions_default_fold_state: "Versions will not be expanded by default when viewing backlogs. Each one has to be manually expanded." diff --git a/modules/backlogs/spec/features/projects/backlogs_settings_spec.rb b/modules/backlogs/spec/features/projects/backlogs_settings_spec.rb new file mode 100644 index 000000000000..32e090f31376 --- /dev/null +++ b/modules/backlogs/spec/features/projects/backlogs_settings_spec.rb @@ -0,0 +1,96 @@ +# frozen_string_literal: true + +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +#++ + +require "spec_helper" +require_relative "../../support/pages/projects/settings/backlogs" + +RSpec.describe "Backlogs Project Settings", :js do + let!(:project) do + create(:project, + enabled_module_names: %w(backlogs)) + end + let!(:closed_status) { create(:status, name: "Closed", is_closed: true) } + let!(:closed_like_status) { create(:status, name: "Sorta kinda Finished", is_default: true) } + let(:role) do + create(:project_role, + permissions: %i[select_done_statuses]) + end + let!(:current_user) do + create(:user, + member_with_roles: { project => role }) + end + let(:settings_page) { Pages::Projects::Settings::Backlogs.new(project) } + let(:done_status_ids_autocompleter) { FormFields::Primerized::AutocompleteField.new("story_types", selector: "[data-test-selector='done_status_ids_autocomplete']") } + + before do + login_as current_user + end + + it "allows setting a status as done although it is not closed" do + settings_page.visit! + + expect(page).to have_heading "Backlogs" + + wait_for_network_idle + wait_for_autocompleter_options_to_be_loaded + + done_status_ids_autocompleter.expect_blank + done_status_ids_autocompleter.select_option "Closed" + done_status_ids_autocompleter.select_option "Sorta kinda Finished" + + done_status_ids_autocompleter.expect_selected "Closed" + done_status_ids_autocompleter.expect_selected "Sorta kinda Finished" + done_status_ids_autocompleter.expect_not_disabled "Definition of Done" + + done_status_ids_autocompleter.close_autocompleter + + click_button "Save" + + expect_flash(type: :success, message: "Successful update") + + wait_for_network_idle + wait_for_autocompleter_options_to_be_loaded + + done_status_ids_autocompleter.expect_selected "Closed" + done_status_ids_autocompleter.expect_selected "Sorta kinda Finished" + + done_status_ids_autocompleter.deselect_option "Sorta kinda Finished" + + click_button "Save" + + wait_for_network_idle + wait_for_autocompleter_options_to_be_loaded + + expect_flash(type: :success, message: "Successful update") + + done_status_ids_autocompleter.expect_selected "Closed" + done_status_ids_autocompleter.expect_not_selected "Sorta kinda Finished" + end +end