From f4281408e8d02ade017db971b6750cb7627ebbd7 Mon Sep 17 00:00:00 2001 From: Klaus Zanders Date: Thu, 9 Apr 2026 11:32:06 +0200 Subject: [PATCH] Add departmetn adding behavior --- .../add_department_component.html.erb | 73 +++++++++++++++++++ .../departments/add_department_component.rb | 46 ++++++++++++ .../admin/departments/blankslate_component.rb | 7 +- .../departments/detail_component.html.erb | 10 ++- .../hierarchy_layout_component.html.erb | 6 +- .../admin/departments_controller.rb | 15 ++++ .../admin/departments/new_department.html.erb | 8 ++ config/locales/en.yml | 3 + config/routes.rb | 2 + 9 files changed, 164 insertions(+), 6 deletions(-) create mode 100644 app/components/admin/departments/add_department_component.html.erb create mode 100644 app/components/admin/departments/add_department_component.rb create mode 100644 app/views/admin/departments/new_department.html.erb diff --git a/app/components/admin/departments/add_department_component.html.erb b/app/components/admin/departments/add_department_component.html.erb new file mode 100644 index 00000000000..9cb0f14eeab --- /dev/null +++ b/app/components/admin/departments/add_department_component.html.erb @@ -0,0 +1,73 @@ +<%#-- 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 do + primer_form_with( + url: add_department_admin_departments_path, + method: :post + ) do |f| + cancel_path = if group + helpers.admin_department_path(group) + else + helpers.admin_departments_path + end + + parent_id = group&.id + + render_inline_form(f) do |form| + form.hidden(name: :parent_id, value: parent_id) if parent_id + + form.group(layout: :horizontal) do |row| + row.text_field( + name: :name, + label: I18n.t("departments.add_department_form.name_label"), + visually_hide_label: true, + placeholder: I18n.t("departments.add_department_form.name_placeholder"), + required: true, + autofocus: true, + autocomplete: "off" + ) + row.button( + name: :cancel, + tag: :a, + label: I18n.t(:button_cancel), + scheme: :default, + href: cancel_path + ) + row.submit( + name: :submit, + label: I18n.t(:button_add), + scheme: :primary + ) + end + end + end + end +%> diff --git a/app/components/admin/departments/add_department_component.rb b/app/components/admin/departments/add_department_component.rb new file mode 100644 index 00000000000..29401cea457 --- /dev/null +++ b/app/components/admin/departments/add_department_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 Admin + module Departments + class AddDepartmentComponent < ApplicationComponent + include ApplicationHelper + include OpTurbo::Streamable + include OpPrimer::ComponentHelpers + + attr_reader :group + + def initialize(group:) + super() + @group = group + end + end + end +end diff --git a/app/components/admin/departments/blankslate_component.rb b/app/components/admin/departments/blankslate_component.rb index 139a333beea..525a091af0c 100644 --- a/app/components/admin/departments/blankslate_component.rb +++ b/app/components/admin/departments/blankslate_component.rb @@ -31,6 +31,7 @@ module Admin module Departments class BlankslateComponent < ApplicationComponent + include ApplicationHelper include OpPrimer::ComponentHelpers def call @@ -38,7 +39,11 @@ module Admin component.with_visual_icon(icon: :people, size: :medium) component.with_heading(tag: :h2) { t("departments.blankslate.heading") } component.with_description { t("departments.blankslate.description") } - component.with_primary_action(href: "#", scheme: :primary) do |button| + component.with_primary_action( + href: new_department_admin_departments_path, + scheme: :primary, + data: { turbo_frame: Admin::Departments::DetailComponent.wrapper_key } + ) do |button| button.with_leading_visual_icon(icon: :plus) t("departments.blankslate.add_button") end diff --git a/app/components/admin/departments/detail_component.html.erb b/app/components/admin/departments/detail_component.html.erb index 7b768122253..c368aba2f08 100644 --- a/app/components/admin/departments/detail_component.html.erb +++ b/app/components/admin/departments/detail_component.html.erb @@ -56,11 +56,11 @@ See COPYRIGHT and LICENSE files for more details. end end - if show_global_empty_state? && !add_user? + if show_global_empty_state? && !add_subgroup? box.with_row do render(Admin::Departments::BlankslateComponent.new) end - elsif show_department_empty_state? && !add_user? + elsif show_department_empty_state? && !add_user? && !add_subgroup? box.with_row do render(Admin::Departments::DetailBlankslateComponent.new) end @@ -83,6 +83,12 @@ See COPYRIGHT and LICENSE files for more details. render(Admin::Departments::AddUserComponent.new(group:)) end end + + if add_subgroup? + box.with_row do + render(Admin::Departments::AddDepartmentComponent.new(group:)) + end + end end end %> diff --git a/app/components/admin/departments/hierarchy_layout_component.html.erb b/app/components/admin/departments/hierarchy_layout_component.html.erb index 81995bf9fd3..3f6d8dbbbdd 100644 --- a/app/components/admin/departments/hierarchy_layout_component.html.erb +++ b/app/components/admin/departments/hierarchy_layout_component.html.erb @@ -36,7 +36,7 @@ See COPYRIGHT and LICENSE files for more details. flex_layout do |main| main.with_row do render(Primer::OpenProject::SubHeader.new) do |subheader| - subheader.with_action_menu(leading_icon: :plus, label: I18n.t(:button_add), button_arguments: { scheme: :primary, "aria-label": I18n.t(:button_add) }) do |menu| + subheader.with_action_menu(leading_icon: :plus, trailing_icon: :"triangle-down", label: I18n.t(:button_add), button_arguments: { scheme: :primary, "aria-label": I18n.t(:button_add) }) do |menu| if active_group menu.with_item( label: I18n.t("departments.add_user"), @@ -48,8 +48,8 @@ See COPYRIGHT and LICENSE files for more details. menu.with_item( label: I18n.t("departments.add_department"), tag: :a, - href: "#", - content_arguments: { data: { turbo_stream: true } } + href: new_department_admin_departments_path(parent_id: active_group&.id), + content_arguments: { data: { turbo_frame: Admin::Departments::DetailComponent.wrapper_key } } ) end end diff --git a/app/controllers/admin/departments_controller.rb b/app/controllers/admin/departments_controller.rb index e6dacc42629..d36c8caed05 100644 --- a/app/controllers/admin/departments_controller.rb +++ b/app/controllers/admin/departments_controller.rb @@ -55,6 +55,21 @@ module Admin # TODO: Implement end + def new_department + @group = Group.visible.with_detail.organizational_units.find(params[:parent_id]) if params[:parent_id].present? + + if @group + @child_groups = @group.children + @ancestors = @group.ancestors(order: :asc) + else + @child_groups = Group.with_detail.organizational_units.visible.where_detail(parent_id: nil).order(:lastname) + end + end + + def add_department + # TODO: Implement + end + def edit_organization_name replace_via_turbo_stream(component: Admin::Departments::OrganizationNameFormComponent.new) respond_with_turbo_streams diff --git a/app/views/admin/departments/new_department.html.erb b/app/views/admin/departments/new_department.html.erb new file mode 100644 index 00000000000..197f97661e2 --- /dev/null +++ b/app/views/admin/departments/new_department.html.erb @@ -0,0 +1,8 @@ +<%= render( + Admin::Departments::DetailComponent.new( + group: @group, + ancestors: @ancestors || [], + child_groups: @child_groups, + add_subgroup: true + ) + ) %> diff --git a/config/locales/en.yml b/config/locales/en.yml index 065532e1457..016a9d998ae 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -734,6 +734,9 @@ en: heading: "This department doesn’t have any hierarchy level below" description: "Add departments or users to create sub-items inside another one." add_button: "Add" + add_department_form: + name_label: "Department name" + name_placeholder: "Enter department name" pagination: label: "Pagination" diff --git a/config/routes.rb b/config/routes.rb index da45ebbfd77..e4e584fff76 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -819,6 +819,8 @@ Rails.application.routes.draw do end collection do + get :new_department + post :add_department get :edit_organization_name patch :cancel_edit_organization_name patch :update_organization_name