diff --git a/app/components/projects/concerns/identifier_suggestion.rb b/app/components/projects/concerns/identifier_suggestion.rb new file mode 100644 index 000000000000..2c9709531805 --- /dev/null +++ b/app/components/projects/concerns/identifier_suggestion.rb @@ -0,0 +1,46 @@ +# 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. +# ++ + +module Projects + module Concerns + module IdentifierSuggestion + def identifier_suggestion_data + suggestion_mode = Setting::WorkPackageIdentifier.alphanumeric? ? "semantic" : "legacy" + + { + controller: "projects--identifier-suggestion", + "projects--identifier-suggestion-mode-value": suggestion_mode, + "projects--identifier-suggestion-url-value": projects_identifier_suggestion_path, + "projects--identifier-suggestion-set-name-first-value": I18n.t("js.projects.identifier_suggestion.set_name_first") + } + end + end + end +end diff --git a/app/components/projects/copy_form_component.html.erb b/app/components/projects/copy_form_component.html.erb index fc8b4d6de6d9..e2c7cc46b658 100644 --- a/app/components/projects/copy_form_component.html.erb +++ b/app/components/projects/copy_form_component.html.erb @@ -28,7 +28,7 @@ See COPYRIGHT and LICENSE files for more details. ++#%> <%= - component_wrapper do + component_wrapper(data: identifier_suggestion_data) do settings_primer_form_with(model: target_project, url: copy_project_path(source_project), method: :post) do |f| flex_layout do |container| container.with_row(mb: 3) do @@ -41,6 +41,7 @@ See COPYRIGHT and LICENSE files for more details. render( Primer::Forms::FormList.new( Projects::Settings::NameForm.new(f), + Projects::Settings::EditableIdentifierForm.new(f), Projects::Settings::RelationsForm.new(f, invisible: params[:parent_id].present?), Projects::Settings::CustomFieldsForm.new(f) ) diff --git a/app/components/projects/copy_form_component.rb b/app/components/projects/copy_form_component.rb index 9d1cefd0d773..86913f685259 100644 --- a/app/components/projects/copy_form_component.rb +++ b/app/components/projects/copy_form_component.rb @@ -33,6 +33,7 @@ class CopyFormComponent < ApplicationComponent include ApplicationHelper include OpPrimer::ComponentHelpers include OpTurbo::Streamable + include Projects::Concerns::IdentifierSuggestion options :source_project, :target_project, :copy_options end diff --git a/app/components/projects/new_component.rb b/app/components/projects/new_component.rb index b646a3f0edf0..ffe2faeae9d1 100644 --- a/app/components/projects/new_component.rb +++ b/app/components/projects/new_component.rb @@ -33,6 +33,7 @@ class NewComponent < ApplicationComponent include ApplicationHelper include OpPrimer::ComponentHelpers include OpTurbo::Streamable + include Projects::Concerns::IdentifierSuggestion options :project, :template, :step @@ -44,17 +45,6 @@ def step_3_display { display: :none } unless step == 3 end - def identifier_suggestion_data - suggestion_mode = Setting::WorkPackageIdentifier.alphanumeric? ? "semantic" : "legacy" - - { - controller: "projects--identifier-suggestion", - "projects--identifier-suggestion-mode-value": suggestion_mode, - "projects--identifier-suggestion-url-value": projects_identifier_suggestion_path, - "projects--identifier-suggestion-set-name-first-value": I18n.t("js.projects.identifier_suggestion.set_name_first") - } - end - def workspaces_path workspace_type = if Project.workspace_types.key?(project.workspace_type) project.workspace_type diff --git a/spec/components/projects/copy_form_component_spec.rb b/spec/components/projects/copy_form_component_spec.rb index b1933497ebc1..6a7537d414b5 100644 --- a/spec/components/projects/copy_form_component_spec.rb +++ b/spec/components/projects/copy_form_component_spec.rb @@ -33,6 +33,7 @@ RSpec.describe Projects::CopyFormComponent, type: :component do let(:source_project) { build_stubbed(:project) } let(:target_project) { Project.new(attributes_for(:project).except(:name)) } + let(:rendered_component) { render_component } def render_component(**params) render_inline(described_class.new(source_project:, target_project:, **params)) @@ -40,6 +41,10 @@ def render_component(**params) end it "renders a form" do - expect(render_component).to have_css "form" + expect(rendered_component).to have_css "form" + end + + describe "#identifier_suggestion_data" do + it_behaves_like "renders identifier_suggestion_data" end end diff --git a/spec/components/projects/new_component_spec.rb b/spec/components/projects/new_component_spec.rb index b43e6df0ec43..1d93a3427fc0 100644 --- a/spec/components/projects/new_component_spec.rb +++ b/spec/components/projects/new_component_spec.rb @@ -83,33 +83,6 @@ end describe "#identifier_suggestion_data" do - subject(:rendered) { render_inline(described_class.new(project:)) } - - it "mounts the Stimulus controller on the wrapper" do - expect(rendered).to have_css("[data-controller='projects--identifier-suggestion']") - end - - it "includes the suggestion URL" do - expect(rendered).to have_css("[data-projects--identifier-suggestion-url-value='/projects/identifier_suggestion']") - end - - it "includes the set_name_first translation" do - translation = I18n.t("js.projects.identifier_suggestion.set_name_first") - expect(rendered).to have_css( - "[data-projects--identifier-suggestion-set-name-first-value='#{translation}']" - ) - end - - context "with alphanumeric identifiers", with_settings: { work_packages_identifier: "alphanumeric" } do - it "sets mode to semantic" do - expect(rendered).to have_css("[data-projects--identifier-suggestion-mode-value='semantic']") - end - end - - context "with numeric identifiers", with_settings: { work_packages_identifier: "numeric" } do - it "sets mode to legacy" do - expect(rendered).to have_css("[data-projects--identifier-suggestion-mode-value='legacy']") - end - end + it_behaves_like "renders identifier_suggestion_data" end end diff --git a/spec/support/shared/components/identifier_suggestion_data.rb b/spec/support/shared/components/identifier_suggestion_data.rb new file mode 100644 index 000000000000..65bf6a26e4e3 --- /dev/null +++ b/spec/support/shared/components/identifier_suggestion_data.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +RSpec.shared_examples "renders identifier_suggestion_data" do + it "mounts the Stimulus controller on the wrapper" do + expect(rendered_component).to have_css("[data-controller='projects--identifier-suggestion']") + end + + it "includes the suggestion URL" do + expect(rendered_component).to have_css( + "[data-projects--identifier-suggestion-url-value='/projects/identifier_suggestion']" + ) + end + + it "includes the set_name_first translation" do + translation = I18n.t("js.projects.identifier_suggestion.set_name_first") + expect(rendered_component).to have_css( + "[data-projects--identifier-suggestion-set-name-first-value='#{translation}']" + ) + end + + context "with alphanumeric identifiers", with_settings: { work_packages_identifier: "alphanumeric" } do + it "sets mode to semantic" do + expect(rendered_component).to have_css("[data-projects--identifier-suggestion-mode-value='semantic']") + end + end + + context "with numeric identifiers", with_settings: { work_packages_identifier: "numeric" } do + it "sets mode to legacy" do + expect(rendered_component).to have_css("[data-projects--identifier-suggestion-mode-value='legacy']") + end + end +end