mirror of
https://github.com/opf/openproject.git
synced 2026-06-14 03:30:14 +00:00
Merge pull request #20347 from opf/implementation/67462-add-filterable-tree-view-component-to-dialog
[#67462] Add filterable tree view for parent selection
This commit is contained in:
+12
-5
@@ -28,18 +28,25 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
++#%>
|
||||
|
||||
<%=
|
||||
render Primer::Alpha::Dialog.new(id: dialog_id, title: I18n.t(:label_change_parent)) do |dialog|
|
||||
render(
|
||||
Primer::Alpha::Dialog.new(
|
||||
id: dialog_id,
|
||||
title: I18n.t(:label_change_parent),
|
||||
size: :medium_portrait
|
||||
)
|
||||
) do |dialog|
|
||||
dialog.with_body do
|
||||
primer_form_with(**form_arguments) do |f|
|
||||
helpers.render_inline_form(f) do |form|
|
||||
form.text_field(name: :new_parent, label: "New Parent")
|
||||
primer_form_with(**form_arguments) do |form|
|
||||
render(
|
||||
Primer::OpenProject::FilterableTreeView.new(form_arguments: { builder: form, name: :new_parent })
|
||||
) do |tree_view|
|
||||
add_sub_tree(tree_view, hierarchy_items)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
dialog.with_footer(show_divider: true) do
|
||||
concat(render(Primer::Beta::Button.new(data: { close_dialog_id: dialog_id })) { I18n.t(:button_cancel) })
|
||||
|
||||
concat(
|
||||
render(
|
||||
Primer::Beta::Button.new(
|
||||
|
||||
+35
-2
@@ -48,17 +48,50 @@ module Admin
|
||||
|
||||
def form_arguments
|
||||
{
|
||||
form_id:,
|
||||
id: form_id,
|
||||
url: change_parent_custom_field_item_path(custom_field_id: @custom_field.id, id: @hierarchy_item.id),
|
||||
model: form_model,
|
||||
method: :post
|
||||
}
|
||||
end
|
||||
|
||||
def hierarchy_items
|
||||
hashed_hierarchy = @custom_field.hierarchy_root.hash_tree
|
||||
hashed_hierarchy.keys.first.label = @custom_field.name
|
||||
|
||||
hashed_hierarchy
|
||||
end
|
||||
|
||||
def add_sub_tree(tree, hierarchy_hash)
|
||||
hierarchy_hash.each do |item, child_hash|
|
||||
if child_hash.empty?
|
||||
tree.with_leaf(**item_options(item))
|
||||
else
|
||||
expanded = current?(item) || child_hash.any? { |child, _| current?(child) }
|
||||
|
||||
tree.with_sub_tree(expanded:, **item_options(item)) do |sub_tree|
|
||||
add_sub_tree(sub_tree, child_hash)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def form_model
|
||||
CustomField::Hierarchy::Forms::NewParentFormModel.new(new_parent: nil)
|
||||
CustomField::Hierarchy::Forms::NewParentFormModel.new(new_parent: [])
|
||||
end
|
||||
|
||||
def item_options(item)
|
||||
{
|
||||
label: item.label,
|
||||
current: current?(item),
|
||||
value: item.id
|
||||
}
|
||||
end
|
||||
|
||||
def current?(item)
|
||||
item.id == @hierarchy_item.id
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -33,6 +33,7 @@ module Admin
|
||||
module Hierarchy
|
||||
class ItemsController < ApplicationController
|
||||
include OpTurbo::ComponentStream
|
||||
include Dry::Monads[:result]
|
||||
|
||||
layout :admin_or_frame_layout
|
||||
model_object CustomField
|
||||
@@ -103,11 +104,25 @@ module Admin
|
||||
end
|
||||
|
||||
def change_parent
|
||||
permitted = params.expect(custom_field_hierarchy_forms_new_parent_form_model: [:new_parent])
|
||||
new_parent = CustomField::Hierarchy::Item.including_children.find(permitted[:new_parent])
|
||||
item_service.move_item(item: @active_item, new_parent:)
|
||||
result = parse_parent_input(new_parent_params).bind do |new_parent|
|
||||
validate_new_parent(new_parent).bind do
|
||||
item_service.move_item(item: @active_item, new_parent:)
|
||||
end
|
||||
end
|
||||
|
||||
redirect_to(custom_field_item_path(@custom_field, new_parent), status: :see_other)
|
||||
result.either(
|
||||
->(result) do
|
||||
redirect_to(
|
||||
custom_field_item_path(@custom_field, result.parent),
|
||||
status: :see_other,
|
||||
notice: I18n.t(:notice_successful_update)
|
||||
)
|
||||
end,
|
||||
->(error) do
|
||||
render_error_flash_message_via_turbo_stream(message: error)
|
||||
respond_with_turbo_streams(&:html)
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
def destroy
|
||||
@@ -147,6 +162,10 @@ module Admin
|
||||
input
|
||||
end
|
||||
|
||||
def new_parent_params
|
||||
params.require(:custom_field_hierarchy_forms_new_parent_form_model).require(:new_parent)
|
||||
end
|
||||
|
||||
def create_contract
|
||||
case @custom_field.field_format
|
||||
when "hierarchy"
|
||||
@@ -184,6 +203,29 @@ module Admin
|
||||
end
|
||||
end
|
||||
|
||||
def parse_parent_input(new_parent_input)
|
||||
case new_parent_input
|
||||
in [new_parent]
|
||||
input = MultiJson.load(new_parent, symbolize_keys: true)[:value]
|
||||
new_parent = CustomField::Hierarchy::Item.including_children.find_by(id: input)
|
||||
|
||||
if new_parent.present?
|
||||
Success(new_parent)
|
||||
else
|
||||
Failure("Cannot find parent with id: #{input}")
|
||||
end
|
||||
else
|
||||
Failure("Invalid input: #{new_parent_input}")
|
||||
end
|
||||
end
|
||||
|
||||
def validate_new_parent(new_parent)
|
||||
return Failure("Parent must not be the same as before.") if @active_item.parent.id == new_parent.id
|
||||
return Failure("Parent must not be the current item.") if @active_item.id == new_parent.id
|
||||
|
||||
Success()
|
||||
end
|
||||
|
||||
def find_model_object
|
||||
@object = CustomField.hierarchy_root_and_children.find(params[:custom_field_id])
|
||||
@custom_field = @object
|
||||
|
||||
Reference in New Issue
Block a user