From cf3567973d42a92f5cd2a0d564543b4e2f47430f Mon Sep 17 00:00:00 2001 From: Eric Schubert Date: Wed, 22 Jan 2025 16:12:30 +0100 Subject: [PATCH 1/4] [#60144] primerize wp types settings form - https://community.openproject.org/work_packages/60144 - remove old form for new and edit - add primer form component --- .../types/settings_component.html.erb | 34 ++++++ .../work_packages/types/settings_component.rb | 46 ++++++++ app/controllers/types_controller.rb | 6 +- .../work_packages/types/settings_form.rb | 108 ++++++++++++++++++ app/helpers/types_helper.rb | 4 +- app/views/types/form/_settings.html.erb | 75 ------------ app/views/types/new.html.erb | 6 +- .../open_project/forms/color_select.html.erb | 2 +- 8 files changed, 194 insertions(+), 87 deletions(-) create mode 100644 app/components/work_packages/types/settings_component.html.erb create mode 100644 app/components/work_packages/types/settings_component.rb create mode 100644 app/forms/work_packages/types/settings_form.rb delete mode 100644 app/views/types/form/_settings.html.erb diff --git a/app/components/work_packages/types/settings_component.html.erb b/app/components/work_packages/types/settings_component.html.erb new file mode 100644 index 000000000000..f9c74101ee83 --- /dev/null +++ b/app/components/work_packages/types/settings_component.html.erb @@ -0,0 +1,34 @@ +<%#-- 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. + +++#%> + +<%= + primer_form_with(**form_options) do |f| + render(WorkPackages::Types::SettingsForm.new(f)) + end +%> diff --git a/app/components/work_packages/types/settings_component.rb b/app/components/work_packages/types/settings_component.rb new file mode 100644 index 000000000000..fa08b10fbbba --- /dev/null +++ b/app/components/work_packages/types/settings_component.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 WorkPackages + module Types + class SettingsComponent < ApplicationComponent + include OpPrimer::ComponentHelpers + include OpTurbo::Streamable + + def form_options + { + url: model.new_record? ? types_path : type_path(id: model.id), + method: model.new_record? ? :post : :patch, + model: + } + end + end + end +end diff --git a/app/controllers/types_controller.rb b/app/controllers/types_controller.rb index 3c2bf3b7293e..939264122d90 100644 --- a/app/controllers/types_controller.rb +++ b/app/controllers/types_controller.rb @@ -62,7 +62,7 @@ def edit end end - def create # rubocop:disable Metrics/AbcSize + def create CreateTypeService .new(current_user) .call(permitted_type_params, copy_workflow_from: params[:copy_workflow_from]) do |call| @@ -72,9 +72,7 @@ def create # rubocop:disable Metrics/AbcSize redirect_to_type_tab_path(@type, t(:notice_successful_create)) end - call.on_failure do |result| - flash[:error] = result.errors.full_messages.join("\n") - load_projects_and_types + call.on_failure do render action: :new, status: :unprocessable_entity end end diff --git a/app/forms/work_packages/types/settings_form.rb b/app/forms/work_packages/types/settings_form.rb new file mode 100644 index 000000000000..e9bcdcbcab1c --- /dev/null +++ b/app/forms/work_packages/types/settings_form.rb @@ -0,0 +1,108 @@ +# 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 WorkPackages + module Types + class SettingsForm < ApplicationForm + form do |subject_form| + subject_form.text_field( + name: :name, + label: label(:name), + placeholder: I18n.t(:label_name), + input_width: :large, + required: true, + disabled: model.is_standard? + ) + + subject_form.color_select_list( + name: :color_id, + label: Color.model_name.human, + caption: I18n.t("types.edit.settings.type_color_text"), + input_width: :large + ) + + if show_work_flow_copy? + subject_form.select_list( + name: :copy_workflow_from, + label: label(:copy_workflow_from), + include_blank: true, + input_width: :large + ) do |other_types| + work_package_types.each do |type| + other_types.option(value: type.id, label: type.name) + end + end + end + + subject_form.rich_text_area( + name: :description, + label: label(:description), + input_width: :large, + rich_text_options: { showAttachments: false } + ) + + subject_form.check_box( + name: :is_milestone, + label: label(:is_milestone) + ) + + subject_form.check_box( + name: :is_in_roadmap, + label: label(:is_in_roadmap) + ) + + subject_form.check_box( + name: :is_default, + label: label(:is_default) + ) + + subject_form.submit( + name: :submit, + label: I18n.t(:button_save), + scheme: :primary + ) + end + + private + + def label(attribute) + model.class.human_attribute_name(attribute) + end + + def show_work_flow_copy? + model.new_record? + end + + def work_package_types + Type.all + end + end + end +end diff --git a/app/helpers/types_helper.rb b/app/helpers/types_helper.rb index 934ce2ed2e7b..2e9c38b7012a 100644 --- a/app/helpers/types_helper.rb +++ b/app/helpers/types_helper.rb @@ -34,9 +34,9 @@ def types_tabs tabs = [ { name: "settings", - partial: "types/form/settings", path: edit_tab_type_path(id: @type.id, tab: :settings), - label: "types.edit.settings.tab" + label: "types.edit.settings.tab", + view_component: WorkPackages::Types::SettingsComponent }, { name: "form_configuration", diff --git a/app/views/types/form/_settings.html.erb b/app/views/types/form/_settings.html.erb deleted file mode 100644 index 13ba08e6a564..000000000000 --- a/app/views/types/form/_settings.html.erb +++ /dev/null @@ -1,75 +0,0 @@ -<%#-- 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. - -++#%> - -
-
- -
<%= f.text_field :name, required: true, disabled: @type.is_standard?, container_class: '-middle' %>
-
<%= f.check_box :is_in_roadmap %>
- <%= render partial: '/colors/color_autocomplete_field', - locals: { - form: f, - object: @type, - type: 'type', - highlight_text_inline: true, - label: t('types.edit.settings.type_color_text'), - form_field_class: '-wide-label', - container_class: '-slim' - } %> -
<%= f.check_box :is_default %>
-
<%= f.check_box :is_milestone %>
- - <% if @type.new_record? && @types.any? %> -
- <%= styled_label_tag 'copy_workflow_from', t(:label_copy_workflow_from) %> - <%= styled_select_tag(:copy_workflow_from, - options_from_collection_for_select(@types, :id, :name, params[:copy_workflow_from]), - include_blank: true, - container_class: '-slim') %> -
- <% end %> - -
- <%= f.text_area :description, - class: 'wiki-edit wiki-toolbar', - container_class: '-xxwide', - with_text_formatting: true %> -
- - - -
-
- -
-
- <%= styled_button_tag t(@type.new_record? ? :button_create : :button_save), - class: '-primary -with-icon icon-checkmark' %> -
-
diff --git a/app/views/types/new.html.erb b/app/views/types/new.html.erb index 60cc30a16a0e..4b937fc9b359 100644 --- a/app/views/types/new.html.erb +++ b/app/views/types/new.html.erb @@ -39,8 +39,4 @@ See COPYRIGHT and LICENSE files for more details. end %> -<%= error_messages_for 'type' %> - -<%= form_for controller.type, builder: TabularFormBuilder, lang: current_language do |f| %> - <%= render partial: 'types/form/settings', locals: { f: f } %> -<% end %> +<%= render WorkPackages::Types::SettingsComponent.new(@type) %> diff --git a/lib/primer/open_project/forms/color_select.html.erb b/lib/primer/open_project/forms/color_select.html.erb index a6678dce90de..fe59102fab55 100644 --- a/lib/primer/open_project/forms/color_select.html.erb +++ b/lib/primer/open_project/forms/color_select.html.erb @@ -2,7 +2,7 @@ <%= content_tag(:div, **@field_wrap_arguments) do %> <%= builder.hidden_field :color_id %> <%= angular_component_tag("opce-colors-autocompleter", - class: "colors-autocomplete form--select-container -middle", + class: "colors-autocomplete form--select-container", data: { colors:, classes: "ng-select--primerized", From 9850e04e0b25d6719aa4c0d7e8eb5a09246212bb Mon Sep 17 00:00:00 2001 From: Eric Schubert Date: Fri, 24 Jan 2025 15:03:31 +0100 Subject: [PATCH 2/4] [#60144] fixed types controller test --- spec/controllers/types_controller_spec.rb | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/spec/controllers/types_controller_spec.rb b/spec/controllers/types_controller_spec.rb index 15bbc7bbc910..1a01a7ef299f 100644 --- a/spec/controllers/types_controller_spec.rb +++ b/spec/controllers/types_controller_spec.rb @@ -41,8 +41,8 @@ is_for_all: true) end let(:custom_field_2) { create(:work_package_custom_field) } - let(:status_0) { create(:status) } - let(:status_1) { create(:status) } + let(:status_old) { create(:status) } + let(:status_new) { create(:status) } context "with an unauthorized account" do let(:current_user) { create(:user) } @@ -174,8 +174,8 @@ let!(:existing_type) { create(:type, name: "Existing type") } let!(:workflow) do create(:workflow, - old_status: status_0, - new_status: status_1, + old_status: status_old, + new_status: status_new, type_id: existing_type.id) end @@ -218,7 +218,6 @@ it { expect(response).to have_http_status(:ok) } it { expect(response).to render_template "edit" } - it { expect(response).to render_template "types/form/_settings" } it { expect(response.body).to have_css "input[@name='type[name]'][@value='My type']" } it { expect(response.body).to have_css "input[@name='type[is_milestone]'][@value='1'][@checked='checked']" } end From af0a31dc50b453f0790161f6d34db3ad26d17fe4 Mon Sep 17 00:00:00 2001 From: Eric Schubert Date: Mon, 27 Jan 2025 15:37:20 +0100 Subject: [PATCH 3/4] [#60144] retain and submit copy workflow value - fetch correct parameter for copy workflow value on form submission - initialize form with this parameter if available - fix feature spec with new UI --- .../work_packages/types/settings_component.rb | 8 +++++- app/controllers/types_controller.rb | 2 +- .../work_packages/types/settings_form.rb | 28 ++++++++++++------- app/views/types/new.html.erb | 8 +++++- spec/controllers/types_controller_spec.rb | 12 +++++--- spec/features/types/crud_spec.rb | 25 ++++++++--------- 6 files changed, 53 insertions(+), 30 deletions(-) diff --git a/app/components/work_packages/types/settings_component.rb b/app/components/work_packages/types/settings_component.rb index fa08b10fbbba..8cceabe49eab 100644 --- a/app/components/work_packages/types/settings_component.rb +++ b/app/components/work_packages/types/settings_component.rb @@ -34,11 +34,17 @@ class SettingsComponent < ApplicationComponent include OpPrimer::ComponentHelpers include OpTurbo::Streamable + def initialize(model, **options) + @copy_workflow_from = options[:copy_workflow_from].to_i + super + end + def form_options { url: model.new_record? ? types_path : type_path(id: model.id), method: model.new_record? ? :post : :patch, - model: + model:, + copy_workflow_from: @copy_workflow_from } end end diff --git a/app/controllers/types_controller.rb b/app/controllers/types_controller.rb index 939264122d90..c3cc2a5dcbf9 100644 --- a/app/controllers/types_controller.rb +++ b/app/controllers/types_controller.rb @@ -65,7 +65,7 @@ def edit def create CreateTypeService .new(current_user) - .call(permitted_type_params, copy_workflow_from: params[:copy_workflow_from]) do |call| + .call(permitted_type_params, copy_workflow_from: params.dig(:type, :copy_workflow_from)) do |call| @type = call.result call.on_success do diff --git a/app/forms/work_packages/types/settings_form.rb b/app/forms/work_packages/types/settings_form.rb index e9bcdcbcab1c..9b50d854f69d 100644 --- a/app/forms/work_packages/types/settings_form.rb +++ b/app/forms/work_packages/types/settings_form.rb @@ -31,8 +31,8 @@ module WorkPackages module Types class SettingsForm < ApplicationForm - form do |subject_form| - subject_form.text_field( + form do |settings_form| + settings_form.text_field( name: :name, label: label(:name), placeholder: I18n.t(:label_name), @@ -41,7 +41,7 @@ class SettingsForm < ApplicationForm disabled: model.is_standard? ) - subject_form.color_select_list( + settings_form.color_select_list( name: :color_id, label: Color.model_name.human, caption: I18n.t("types.edit.settings.type_color_text"), @@ -49,41 +49,45 @@ class SettingsForm < ApplicationForm ) if show_work_flow_copy? - subject_form.select_list( + settings_form.select_list( name: :copy_workflow_from, label: label(:copy_workflow_from), include_blank: true, input_width: :large ) do |other_types| work_package_types.each do |type| - other_types.option(value: type.id, label: type.name) + other_types.option( + value: type.id, + label: type.name, + selected: type.id == prefilled_copy_workflow_from + ) end end end - subject_form.rich_text_area( + settings_form.rich_text_area( name: :description, label: label(:description), input_width: :large, rich_text_options: { showAttachments: false } ) - subject_form.check_box( + settings_form.check_box( name: :is_milestone, label: label(:is_milestone) ) - subject_form.check_box( + settings_form.check_box( name: :is_in_roadmap, label: label(:is_in_roadmap) ) - subject_form.check_box( + settings_form.check_box( name: :is_default, label: label(:is_default) ) - subject_form.submit( + settings_form.submit( name: :submit, label: I18n.t(:button_save), scheme: :primary @@ -103,6 +107,10 @@ def show_work_flow_copy? def work_package_types Type.all end + + def prefilled_copy_workflow_from + @builder.options[:copy_workflow_from] + end end end end diff --git a/app/views/types/new.html.erb b/app/views/types/new.html.erb index 4b937fc9b359..b1094027dfcd 100644 --- a/app/views/types/new.html.erb +++ b/app/views/types/new.html.erb @@ -39,4 +39,10 @@ See COPYRIGHT and LICENSE files for more details. end %> -<%= render WorkPackages::Types::SettingsComponent.new(@type) %> +<%= + render WorkPackages::Types::SettingsComponent.new( + @type, + copy_workflow_from: params.dig(:type, :copy_workflow_from), + params: + ) +%> diff --git a/spec/controllers/types_controller_spec.rb b/spec/controllers/types_controller_spec.rb index 1a01a7ef299f..afc9d9265149 100644 --- a/spec/controllers/types_controller_spec.rb +++ b/spec/controllers/types_controller_spec.rb @@ -180,10 +180,14 @@ end let(:params) do - { "type" => { name: "New type", - project_ids: { "1" => project.id }, - custom_field_ids: { "1" => custom_field_1.id, "2" => custom_field_2.id } }, - "copy_workflow_from" => existing_type.id } + { + "type" => { + name: "New type", + project_ids: { "1" => project.id }, + custom_field_ids: { "1" => custom_field_1.id, "2" => custom_field_2.id }, + copy_workflow_from: existing_type.id + } + } end before do diff --git a/spec/features/types/crud_spec.rb b/spec/features/types/crud_spec.rb index ede513857a89..a9ea8cf30145 100644 --- a/spec/features/types/crud_spec.rb +++ b/spec/features/types/crud_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + #-- copyright # OpenProject is an open source project management software. # Copyright (C) the OpenProject GmbH @@ -50,21 +52,20 @@ fill_in "Name", with: existing_type.name select existing_type.name, from: "Copy workflow from" - click_button "Create" + click_on "Save" - expect_flash(type: :error, message: "Name has already been taken.") + expect(page).to have_css(".FormControl-inlineValidation", text: "Name has already been taken.", wait: 12) # Values are retained - expect(page) - .to have_field("Name", with: existing_type.name) + expect(page).to have_field("Name", with: existing_type.name) + expect(page).to have_field("Copy workflow from", with: existing_type.id) # Successful creation fill_in "Name", with: "A new type" - click_button "Create" + click_on "Save" - expect(page) - .to have_content I18n.t(:notice_successful_create) + expect(page).to have_content I18n.t(:notice_successful_create) # Workflow should be copied over. # Workflow routes are not resource-oriented. @@ -72,15 +73,14 @@ select existing_role.name, from: "Role" select "A new type", from: "Type" - click_button "Edit" + click_on "Edit" from_id = existing_workflow.old_status_id to_id = existing_workflow.new_status_id checkbox = page.find("input.old-status-#{from_id}.new-status-#{to_id}[value=always]") - expect(checkbox) - .to be_checked + expect(checkbox).to be_checked index_page.visit! @@ -90,10 +90,9 @@ fill_in "Name", with: "Renamed type" - click_button "Save" + click_on "Save" - expect(page) - .to have_content I18n.t(:notice_successful_update) + expect_flash(type: :success, message: I18n.t(:notice_successful_update)) index_page.visit! From 88826fd16a8a1374ef9994c5e5f2e08575c9698b Mon Sep 17 00:00:00 2001 From: Eric Schubert Date: Wed, 29 Jan 2025 14:13:15 +0100 Subject: [PATCH 4/4] [#60144] sanitizing parameter input into settings component - use maybe to convert from parameter value to integer - split create and update form options - add 303 status to redirection in types controller --- .../work_packages/types/settings_component.rb | 29 +++++++++----- app/controllers/types_controller.rb | 2 +- app/helpers/conversion_helper.rb | 39 +++++++++++++++++++ app/views/types/new.html.erb | 7 +--- 4 files changed, 62 insertions(+), 15 deletions(-) create mode 100644 app/helpers/conversion_helper.rb diff --git a/app/components/work_packages/types/settings_component.rb b/app/components/work_packages/types/settings_component.rb index 8cceabe49eab..948af9a38df4 100644 --- a/app/components/work_packages/types/settings_component.rb +++ b/app/components/work_packages/types/settings_component.rb @@ -34,18 +34,29 @@ class SettingsComponent < ApplicationComponent include OpPrimer::ComponentHelpers include OpTurbo::Streamable - def initialize(model, **options) - @copy_workflow_from = options[:copy_workflow_from].to_i - super + def initialize(model, copy_workflow_from: nil, **) + @copy_workflow_from = copy_workflow_from + super(model, **) end def form_options - { - url: model.new_record? ? types_path : type_path(id: model.id), - method: model.new_record? ? :post : :patch, - model:, - copy_workflow_from: @copy_workflow_from - } + if model.new_record? + create_form_options + else + update_form_options + end + end + + private + + attr_reader :copy_workflow_from + + def create_form_options + { url: types_path, method: :post, model:, copy_workflow_from: } + end + + def update_form_options + { url: type_path(id: model.id), method: :patch, model: } end end end diff --git a/app/controllers/types_controller.rb b/app/controllers/types_controller.rb index c3cc2a5dcbf9..57f61b721967 100644 --- a/app/controllers/types_controller.rb +++ b/app/controllers/types_controller.rb @@ -135,7 +135,7 @@ def load_projects_and_types def redirect_to_type_tab_path(type, notice) tab = params["tab"] || "settings" - redirect_to(edit_tab_type_path(type, tab:), notice:) + redirect_to(edit_tab_type_path(type, tab:), notice:, status: :see_other) end def render_edit_tab(type, status: :ok) diff --git a/app/helpers/conversion_helper.rb b/app/helpers/conversion_helper.rb new file mode 100644 index 000000000000..e4ed37cee0e4 --- /dev/null +++ b/app/helpers/conversion_helper.rb @@ -0,0 +1,39 @@ +# 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 ConversionHelper + include Dry::Monads[:maybe] + + def maybe_integer(value) + Some(Integer(value || "", 10)) + rescue ArgumentError + None() + end +end diff --git a/app/views/types/new.html.erb b/app/views/types/new.html.erb index b1094027dfcd..933de72555f4 100644 --- a/app/views/types/new.html.erb +++ b/app/views/types/new.html.erb @@ -40,9 +40,6 @@ See COPYRIGHT and LICENSE files for more details. %> <%= - render WorkPackages::Types::SettingsComponent.new( - @type, - copy_workflow_from: params.dig(:type, :copy_workflow_from), - params: - ) + copy_workflow_from = maybe_integer(params.dig(:type, :copy_workflow_from)).value_or(nil) + render WorkPackages::Types::SettingsComponent.new(@type, copy_workflow_from:) %>