Skip to content

Commit

Permalink
Merge pull request #15700 from opf/implementation/54749-create-add-pr…
Browse files Browse the repository at this point in the history
  • Loading branch information
akabiru authored Jun 5, 2024
2 parents 9336b7b + b842917 commit b842f9f
Show file tree
Hide file tree
Showing 16 changed files with 608 additions and 8 deletions.
1 change: 1 addition & 0 deletions app/components/_index.sass
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
@import "filter/filters_component"
@import "projects/settings/project_custom_field_sections/index_component"
@import "projects/row_component"
@import "settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component"
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<%=
component_wrapper do
render(
Primer::Alpha::Dialog.new(
id: dialog_id,
title:,
test_selector: dialog_id,
size: :large
)
) do |dialog|
dialog.with_show_button(scheme: :primary) do |button|
button.with_leading_visual_icon(icon: 'op-include-projects')
show_button_text
end

dialog.with_header(
show_divider: false,
visually_hide_title: false
)

primer_form_with(
class: "op-new-project-mapping-form",
model: @project_mapping,
url: link_admin_settings_project_custom_field_path(@project_custom_field),
data: { turbo: true },
method: :post
) do |form|
concat(render(Primer::Alpha::Dialog::Body.new(
id: dialog_body_id, test_selector: dialog_body_id, aria: { label: title },
style: "min-height: 300px"
)) do
render(Projects::CustomFields::CustomFieldMappingForm.new(form, project_custom_field: @project_custom_field))
end)

concat(render(Primer::Alpha::Dialog::Footer.new(show_divider: false)) do
concat(render(Primer::ButtonComponent.new(data: { 'close-dialog-id': dialog_id })) { cancel_button_text })
concat(render(Primer::ButtonComponent.new(scheme: :primary, type: :submit)) { submit_button_text })
end)
end
end
end
%>
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) 2012-2023 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 Settings
module ProjectCustomFields
module ProjectCustomFieldMapping
class NewProjectMappingComponent < ApplicationComponent # rubocop:disable OpenProject/AddPreviewForViewComponent
include OpTurbo::Streamable

options dialog_id: "settings--new-project-custom-field-mapping-component",
dialog_body_id: "settings--new-project-custom-field-mapping-body-component"

def initialize(project_mapping:, project_custom_field:, **)
@project_mapping = project_mapping
@project_custom_field = project_custom_field
super(@project_mapping, **)
end

def render?
!@project_custom_field.required?
end

private

def title
I18n.t("projects.settings.project_custom_fields.new_project_mapping_form.add_projects")
end

def show_button_text
I18n.t("projects.settings.project_custom_fields.new_project_mapping_form.add_projects")
end

def cancel_button_text
I18n.t("button_cancel")
end

def submit_button_text
I18n.t("button_add")
end
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
@import 'helpers'

.op-new-project-mapping-form
.ng-placeholder
@extend .icon-search
&:before
@include icon-font-common
margin-right: 10px
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,14 @@ See COPYRIGHT and LICENSE files for more details.
++#%>

<%= component_wrapper(tag: "tr", class: row_css_class, data: { turbo: true }) do %>
<%
wrapper_data_attributes = {
turbo: true,
"projects--settings--available-project-mappings-filter-target": "searchItem"
}
%>

<%= component_wrapper(tag: "tr", class: row_css_class, data: wrapper_data_attributes) do %>
<% columns.each do |column| %>
<td class="<%= column_css_class(column) %>">
<%= column_value(column) %>
Expand Down
55 changes: 48 additions & 7 deletions app/controllers/admin/settings/project_custom_fields_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,11 @@ class ProjectCustomFieldsController < ::Admin::SettingsController
# rubocop:disable Rails/LexicallyScopedActionFilter
before_action :set_sections, only: %i[show index edit update move drop]
before_action :find_custom_field,
only: %i(show edit project_mappings unlink update destroy delete_option reorder_alphabetical move drop)
only: %i(show edit project_mappings link unlink update destroy delete_option reorder_alphabetical move drop)
before_action :prepare_custom_option_position, only: %i(update create)
before_action :find_custom_option, only: :delete_option
before_action :project_custom_field_mappings_query, only: %i[project_mappings unlink]
before_action :find_link_project_custom_field_mapping, only: :link
before_action :find_unlink_project_custom_field_mapping, only: :unlink
# rubocop:enable Rails/LexicallyScopedActionFilter

Expand All @@ -68,14 +69,34 @@ def new

def edit; end

def project_mappings; end
def project_mappings
@project_mapping = ProjectCustomFieldProjectMapping.new(project_custom_field: @custom_field)
end

def link
create_service = ProjectCustomFieldProjectMappings::BulkCreateService
.new(user: current_user, project: @project, project_custom_field: @custom_field,
include_sub_projects: include_sub_projects?)
.call

create_service.on_success { render_project_list }

create_service.on_failure do
update_flash_message_via_turbo_stream(
message: join_flash_messages(create_service.errors.full_messages),
full: true, dismiss_scheme: :hide, scheme: :danger
)
end

respond_to_with_turbo_streams(status: create_service.success? ? :ok : :unprocessable_entity)
end

def unlink
delete_service = ProjectCustomFieldProjectMappings::DeleteService
.new(user: current_user, model: @project_custom_field_mapping)
.call

delete_service.on_success { render_unlink_response }
delete_service.on_success { render_project_list }

delete_service.on_failure do
update_flash_message_via_turbo_stream(
Expand Down Expand Up @@ -126,13 +147,18 @@ def destroy

private

def render_unlink_response
def render_project_list
update_via_turbo_stream(
component: Settings::ProjectCustomFields::ProjectCustomFieldMapping::NewProjectMappingComponent.new(
project_mapping: ProjectCustomFieldProjectMapping.new(project_custom_field: @custom_field),
project_custom_field: @custom_field
)
)
update_via_turbo_stream(
component: Settings::ProjectCustomFields::ProjectCustomFieldMapping::TableComponent.new(
query: @project_custom_field_mappings_query,
query: project_custom_field_mappings_query,
params: { custom_field: @custom_field }
),
status: :ok
)
)
end

Expand Down Expand Up @@ -169,6 +195,17 @@ def find_unlink_project_custom_field_mapping
respond_with_turbo_streams
end

def find_link_project_custom_field_mapping
@project = Project.find(permitted_params.project_custom_field_project_mapping[:project_id])
rescue ActiveRecord::RecordNotFound
update_flash_message_via_turbo_stream(
message: t(:notice_file_not_found), full: true, dismiss_scheme: :hide, scheme: :danger
)
render_project_list

respond_with_turbo_streams
end

def find_custom_field
@custom_field = ProjectCustomField.find(params[:id])
rescue ActiveRecord::RecordNotFound
Expand All @@ -181,5 +218,9 @@ def drop_success_streams(call)
update_section_via_turbo_stream(project_custom_field_section: call.result[:old_section])
end
end

def include_sub_projects?
ActiveRecord::Type::Boolean.new.cast(permitted_params.project_custom_field_project_mapping[:include_sub_projects])
end
end
end
69 changes: 69 additions & 0 deletions app/forms/projects/custom_fields/custom_field_mapping_form.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) 2012-2024 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::CustomFields
class CustomFieldMappingForm < ApplicationForm
form do |f|
f.group(layout: :horizontal) do |f_group|
f_group.project_autocompleter(
name: :id,
label: Project.model_name.human,
visually_hide_label: true,
autocomplete_options: {
openDirectly: false,
focusDirectly: false,
dropdownPosition: "bottom",
disabledProjects: projects_with_custom_field_mapping,
inputName: "project_custom_field_project_mapping[project_id]"
}
)

f_group.check_box(
name: :include_sub_projects,
label: I18n.t("projects.settings.project_custom_fields.new_project_mapping_form.include_sub_projects"),
checked: false,
label_arguments: { class: "no-wrap" }
)
end
end

def initialize(project_custom_field:)
super()
@project_custom_field = project_custom_field
end

private

def projects_with_custom_field_mapping
ProjectCustomFieldProjectMapping
.where(project_custom_field: @project_custom_field)
.pluck(:project_id)
.to_h { |id| [id, id] }
end
end
end
1 change: 1 addition & 0 deletions app/models/permitted_params.rb
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,7 @@ def self.permitted_attributes
project_id
custom_field_id
custom_field_section_id
include_sub_projects
),
query: %i(
name
Expand Down
Loading

0 comments on commit b842f9f

Please sign in to comment.