Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#57816] create hierarchy items #16930

Merged
merged 12 commits into from
Oct 15, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,27 @@ See COPYRIGHT and LICENSE files for more details.
<%=
component_wrapper do
flex_layout do |container|
container.with_row(mb: 3) do
render Primer::Beta::Blankslate.new(border: true) do |component|
component.with_visual_icon(icon: "list-ordered")
component.with_heading(tag: :h3).with_content(I18n.t("custom_fields.admin.items.blankslate.title"))
component.with_description { I18n.t("custom_fields.admin.items.blankslate.description") }
flex_layout(align_items: :center, justify_content: :space_between) do |item_container|
item_container.with_column(flex_layout: true) do |item_information|
item_information.with_column(mr: 2) do
render(Primer::Beta::Text.new(font_weight: :bold)) do
@hierarchy_item.label
end
end
end

container.with_row do
render Primer::Beta::Button.new(scheme: :primary) do |button|
button.with_leading_visual_icon(icon: :plus)
I18n.t(:label_item)
unless @hierarchy_item.short.nil?
item_information.with_column(mr: 2) do
render(Primer::Beta::Text.new(color: :subtle)) { short_text }
end
end
end

# Actions
item_container.with_column do
render(Primer::Beta::IconButton.new(scheme: :default,
icon: "kebab-horizontal",
"aria-label": I18n.t("custom_fields.admin.items.more_actions")))
end
end
end
%>
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@ module Hierarchy
class ItemComponent < ApplicationComponent
include OpTurbo::Streamable
include OpPrimer::ComponentHelpers

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

def short_text
"(#{@hierarchy_item.short})"
end
end
end
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<%#-- 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.
++#%>
<%=
component_wrapper(tag: 'turbo-frame') do
flex_layout do |container|
if items.empty? && !show_new_item_form?
container.with_row(mb: 3) do
render Primer::Beta::Blankslate.new(border: true) do |component|
component.with_visual_icon(icon: "list-ordered")
component.with_heading(tag: :h3).with_content(I18n.t("custom_fields.admin.items.blankslate.title"))
component.with_description { I18n.t("custom_fields.admin.items.blankslate.description") }
end
end
else
container.with_row(mb: 3) do
render(Primer::Beta::BorderBox.new) do |item_box|
item_box.with_header { @custom_field.name }

items.each do |item|
item_box.with_row { render Admin::CustomFields::Hierarchy::ItemComponent.new(hierarchy_item: item) }
end

if show_new_item_form?
item_box.with_footer do
render Admin::CustomFields::Hierarchy::NewItemFormComponent.new(custom_field: @custom_field,
label: @new_item_form_data[:label],
short: @new_item_form_data[:short])
end
end
end
end
end

container.with_row do
render Primer::Beta::Button.new(scheme: :primary,
tag: :a,
data: { turbo_stream: true },
href: new_custom_field_item_path(@custom_field)) do |button|
button.with_leading_visual_icon(icon: :plus)
I18n.t(:label_item)
end
end
end
end
%>
53 changes: 53 additions & 0 deletions app/components/admin/custom_fields/hierarchy/items_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#-- 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 Admin
module CustomFields
module Hierarchy
class ItemsComponent < ApplicationComponent
include OpTurbo::Streamable
include OpPrimer::ComponentHelpers

def initialize(custom_field:, new_item_form_data: { show: false })
super
@custom_field = custom_field
@new_item_form_data = new_item_form_data
end

def items
# TODO: This must be context aware (breadcrumbs)
Kharonus marked this conversation as resolved.
Show resolved Hide resolved
@custom_field.hierarchy_root.children
end

def show_new_item_form?
@new_item_form_data[:show] || false
end
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<%#-- 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(
url: custom_field_items_path(@custom_field),
method: :post,
) do |f|
render(CustomFields::Hierarchy::NewItemForm.new(f, custom_field: @custom_field, label: @label, short: @short))
end
%>
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#-- 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 Admin
module CustomFields
module Hierarchy
class NewItemFormComponent < ApplicationComponent
include OpTurbo::Streamable

def initialize(custom_field:, label: nil, short: nil)
super
@custom_field = custom_field
@label = label
@short = short
end

def items_path
custom_field_items_path(@custom_field)
end
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
module CustomFields
module Hierarchy
class InsertItemContract < Dry::Validation::Contract
config.messages.backend = :i18n

params do
required(:parent).filled
required(:label).filled(:string)
Expand All @@ -49,7 +51,7 @@ class InsertItemContract < Dry::Validation::Contract

rule(:label) do
if CustomField::Hierarchy::Item.exists?(parent_id: values[:parent], label: value)
key.failure("Label must be unique within the same hierarchy level")
key.failure(:not_unique)
end
end
end
Expand Down
37 changes: 37 additions & 0 deletions app/controllers/admin/custom_fields/hierarchy/items_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ module Admin
module CustomFields
module Hierarchy
class ItemsController < ApplicationController
include OpTurbo::ComponentStream

layout "admin"

model_object CustomField
Expand All @@ -43,8 +45,43 @@ class ItemsController < ApplicationController

def index; end

def new
update_via_turbo_stream(component: ItemsComponent.new(custom_field: @custom_field,
new_item_form_data: { show: true }))
respond_with_turbo_streams
end

def create
::CustomFields::Hierarchy::HierarchicalItemService
.new(@custom_field)
.insert_item(**item_input)
.either(
->(_) { update_via_turbo_stream(component: ItemsComponent.new(custom_field: @custom_field)) },
->(validation_result) { add_errors_to_form(validation_result) }
)

respond_with_turbo_streams
end

private

def item_input
input = { parent: @custom_field.hierarchy_root, label: params[:label] }
input[:short] = params[:short] unless params[:short].empty?

input
end

def add_errors_to_form(validation_result)
validation_result.errors(full: true).to_h.each do |attribute, errors|
@custom_field.errors.add(attribute, errors.join(", "))
end

new_item_form_data = { show: true, label: validation_result[:label], short: validation_result[:short] }
update_via_turbo_stream(component: ItemsComponent.new(custom_field: @custom_field, new_item_form_data:),
status: :unprocessable_entity)
end

def find_model_object(object_id = :custom_field_id)
super
@custom_field = @object
Expand Down
3 changes: 2 additions & 1 deletion app/forms/custom_fields/details_form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ class DetailsForm < ApplicationForm

details_form.check_box(
name: :multi_value,
label: I18n.t("activerecord.attributes.custom_field.multi_value")
label: I18n.t("activerecord.attributes.custom_field.multi_value"),
caption: I18n.t("custom_fields.instructions.multi_select")
)

details_form.check_box(
Expand Down
Loading