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

[55179] Harmonize submenu implementations of Meetings, Projects, and Members #15918

Merged
Merged
3 changes: 1 addition & 2 deletions app/components/members/index_page_header_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
class Members::IndexPageHeaderComponent < ApplicationComponent
include OpPrimer::ComponentHelpers
include ApplicationHelper
include Menus::MembersHelper

def initialize(project: nil)
super
Expand Down Expand Up @@ -77,7 +76,7 @@ def current_query
query_name = nil
menu_header = nil

first_level_menu_items.find do |section|
Members::Menu.new(project: @project, params:).menu_items.find do |section|
section.children.find do |menu_query|
if !!menu_query.selected
query_name = menu_query.title
Expand Down
4 changes: 2 additions & 2 deletions app/components/projects/index_page_header_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,9 @@ def current_breadcrumb_element
def current_section
return @current_section if defined?(@current_section)

projects_menu = Menus::Projects.new(controller_path:, params:, current_user:)
projects_menu = Projects::Menu.new(controller_path:, params:, current_user:)

@current_section = projects_menu.first_level_menu_items.find { |section| section.children.any?(&:selected) }
@current_section = projects_menu.menu_items.find { |section| section.children.any?(&:selected) }
end

def header_save_action(header:, message:, label:, href:, method: nil)
Expand Down
4 changes: 1 addition & 3 deletions app/controllers/members/menus_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,11 @@
#++
module Members
class MenusController < ApplicationController
include Menus::MembersHelper

before_action :find_project_by_project_id,
:authorize

def show
@sidebar_menu_items = first_level_menu_items
@sidebar_menu_items = Members::Menu.new(project: @project, params:).menu_items
render layout: nil
end
end
Expand Down
5 changes: 2 additions & 3 deletions app/controllers/projects/menus_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,8 @@ class MenusController < ApplicationController
no_authorization_required! :show

def show
projects_menu = Menus::Projects.new(controller_path: params[:controller_path], params:, current_user:)

@sidebar_menu_items = projects_menu.first_level_menu_items
projects_menu = Projects::Menu.new(controller_path: params[:controller_path], params:, current_user:)
@sidebar_menu_items = projects_menu.menu_items

render layout: nil
end
Expand Down
58 changes: 26 additions & 32 deletions app/helpers/menus/members_helper.rb → app/menus/members/menu.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) 2012-2024 the OpenProject GmbH
# Copyright (C) 2010-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.
Expand All @@ -25,34 +25,30 @@
#
# See COPYRIGHT and LICENSE files for more details.
#++
module Members
class Menu < Submenu
attr_reader :project, :params

module Menus
module MembersHelper
def first_level_menu_items
[OpenProject::Menu::MenuGroup.new(header: nil, children: user_status_options)] + nested_menu_items
def initialize(project: nil, params: nil)
super(view_type: nil, project:, params:)
end

private

def user_status_options
def menu_items
[
OpenProject::Menu::MenuItem.new(title: I18n.t("members.menu.all"),
href: project_members_path,
selected: active_filter_count == 0),
OpenProject::Menu::MenuItem.new(title: I18n.t("members.menu.locked"),
href: project_members_path(status: :locked),
selected: selected?(:status, :locked)),
OpenProject::Menu::MenuItem.new(title: I18n.t("members.menu.invited"),
href: project_members_path(status: :invited),
selected: selected?(:status, :invited))
OpenProject::Menu::MenuGroup.new(header: nil, children: user_status_options),
OpenProject::Menu::MenuGroup.new(header: I18n.t("members.menu.project_roles"), children: project_roles_entries),
OpenProject::Menu::MenuGroup.new(header: I18n.t("members.menu.wp_shares"), children: permission_menu_entries),
OpenProject::Menu::MenuGroup.new(header: I18n.t("members.menu.groups"), children: project_group_entries)
]
end

def nested_menu_items
def user_status_options
[
OpenProject::Menu::MenuGroup.new(header: I18n.t("members.menu.project_roles"), children: project_roles_entries),
OpenProject::Menu::MenuGroup.new(header: I18n.t("members.menu.wp_shares"), children: permission_menu_entries),
OpenProject::Menu::MenuGroup.new(header: I18n.t("members.menu.groups"), children: project_group_entries)
OpenProject::Menu::MenuItem.new(title: I18n.t("members.menu.all"),
href: project_members_path(project),
selected: active_filter_count == 0),
menu_item(I18n.t("members.menu.locked"), status: :locked),
menu_item(I18n.t("members.menu.invited"), status: :invited)
]
end

Expand All @@ -61,13 +57,13 @@ def project_roles_entries
.where(id: MemberRole.where(member_id: @project.members.select(:id)).select(:role_id))
.distinct
.pluck(:id, :name)
.map { |id, name| menu_item(:role_id, id, name) }
.map { |id, name| menu_item(name, role_id: id) }
end

def permission_menu_entries
Members::UserFilterComponent
.share_options
.map { |name, id| menu_item(:shared_role_id, id, name) }
.map { |name, id| menu_item(name, shared_role_id: id) }
end

def project_group_entries
Expand All @@ -76,19 +72,17 @@ def project_group_entries
.order(lastname: :asc)
.distinct
.pluck(:id, :lastname)
.map { |id, name| menu_item(:group_id, id, name) }
.map { |id, name| menu_item(name, group_id: id) }
end

def menu_item(filter_key, id, name)
OpenProject::Menu::MenuItem.new(title: name,
href: project_members_path(filter_key => id),
selected: selected?(filter_key, id))
end

def selected?(filter_key, value)
def selected?(query_params)
return false if active_filter_count > 1

params[filter_key] == value.to_s
super
end

def query_path(query_params)
project_members_path(project, query_params)
end

def active_filter_count
Expand Down
71 changes: 33 additions & 38 deletions app/helpers/menus/projects.rb → app/menus/projects/menu.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,33 +26,50 @@
# See COPYRIGHT and LICENSE files for more details.
#++

module Menus
class Projects
module Projects
class Menu < Submenu
include Rails.application.routes.url_helpers

attr_reader :controller_path, :params, :current_user

def initialize(controller_path:, params:, current_user:)
# rubocop:disable Rails/HelperInstanceVariable
@controller_path = controller_path
def initialize(params:, controller_path:, current_user:)
@params = params
@controller_path = controller_path
@current_user = current_user
# rubocop:enable Rails/HelperInstanceVariable

super(view_type:, project:, params:)
end

def first_level_menu_items
def menu_items
[
OpenProject::Menu::MenuGroup.new(header: nil,
children: main_static_filters),
OpenProject::Menu::MenuGroup.new(header: I18n.t(:"projects.lists.public"),
children: public_filters),
OpenProject::Menu::MenuGroup.new(header: I18n.t(:"projects.lists.my_private"),
children: my_filters),
OpenProject::Menu::MenuGroup.new(header: nil, children: main_static_filters),
OpenProject::Menu::MenuGroup.new(header: I18n.t(:"projects.lists.public"), children: public_filters),
OpenProject::Menu::MenuGroup.new(header: I18n.t(:"projects.lists.my_private"), children: my_filters),
OpenProject::Menu::MenuGroup.new(header: I18n.t(:"activerecord.attributes.project.status_code"),
children: status_static_filters)
]
end

def selected?(query_params)
case controller_path
when "projects"
case params[:query_id]
when nil
query_params[:query_id].to_s == Queries::Projects::Factory::DEFAULT_STATIC
when /\A\d+\z/
query_params[:query_id].to_s == params[:query_id]
else
query_params[:query_id].to_s == params[:query_id] unless modification_params?
end
when "projects/queries"
query_params[:query_id].to_s == params[:id]
end
end

Check notice on line 67 in app/menus/projects/menu.rb

View workflow job for this annotation

GitHub Actions / rubocop

[rubocop] app/menus/projects/menu.rb#L53-L67 <Metrics/AbcSize>

Assignment Branch Condition size for selected? is too high. [<0, 18, 9> 20.12/17]
Raw output
app/menus/projects/menu.rb:53:5: C: Metrics/AbcSize: Assignment Branch Condition size for selected? is too high. [<0, 18, 9> 20.12/17]

def query_path(query_params)
projects_path(query_params)
end

private

def main_static_filters
Expand All @@ -74,44 +91,22 @@

def static_filters(ids)
ids.map do |id|
query_menu_item(::Queries::Projects::Factory.static_query(id), id:)
menu_item(::Queries::Projects::Factory.static_query(id).name, query_id: id)
end
end

def public_filters
::ProjectQuery
.public_lists
.order(:name)
.map { |query| query_menu_item(query) }
.map { |query| menu_item(query.name, query_id: query.id) }
end

def my_filters
::ProjectQuery
.private_lists(user: current_user)
.order(:name)
.map { |query| query_menu_item(query) }
end

def query_menu_item(query, id: nil)
OpenProject::Menu::MenuItem.new(title: query.name,
href: projects_path(query_id: id || query.id),
selected: query_item_selected?(id || query.id))
end

def query_item_selected?(id)
case controller_path
when "projects"
case params[:query_id]
when nil
id.to_s == Queries::Projects::Factory::DEFAULT_STATIC
when /\A\d+\z/
id.to_s == params[:query_id]
else
id.to_s == params[:query_id] unless modification_params?
end
when "projects/queries"
id.to_s == params[:id]
end
.map { |query| menu_item(query.name, query_id: query.id) }
end

def modification_params?
Expand Down
12 changes: 8 additions & 4 deletions app/menus/submenu.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def starred_queries
base_query
.where("starred" => "t")
.pluck(:id, :name)
.map { |id, name| menu_item(query_params(id), name) }
.map { |id, name| menu_item(name, query_params(id)) }
end

def default_queries
Expand All @@ -60,15 +60,15 @@ def global_queries
.where("starred" => "f")
.where("public" => "t")
.pluck(:id, :name)
.map { |id, name| menu_item(query_params(id), name) }
.map { |id, name| menu_item(name, query_params(id)) }
end

def custom_queries
base_query
.where("starred" => "f")
.where("public" => "f")
.pluck(:id, :name)
.map { |id, name| menu_item(query_params(id), name) }
.map { |id, name| menu_item(name, query_params(id)) }
end

def base_query
Expand All @@ -89,7 +89,7 @@ def query_params(id)
{ query_id: id }
end

def menu_item(query_params, name)
def menu_item(name, query_params)
OpenProject::Menu::MenuItem.new(title: name,
href: query_path(query_params),
selected: selected?(query_params))
Expand All @@ -102,6 +102,10 @@ def selected?(query_params)
end
end

if query_params.empty? && params[:filters].present?
return false
end

true
end

Expand Down
2 changes: 1 addition & 1 deletion modules/boards/app/menus/boards/menu.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def global_queries
.references(:project)
.where(project: @project)
.pluck(:id, :name)
.map { |id, name| menu_item(query_params(id), name) }
.map { |id, name| menu_item(name, query_params(id)) }
end

def starred_queries
Expand Down
4 changes: 2 additions & 2 deletions modules/gantt/app/menus/gantt/menu.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ def default_queries
next if params.nil?

menu_item(
params,
I18n.t("js.queries.#{query_key}")
I18n.t("js.queries.#{query_key}"),
params
)
end
end
Expand Down
43 changes: 43 additions & 0 deletions modules/meeting/app/controllers/meetings/menus_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# -- copyright
# OpenProject is an open source project management software.
# Copyright (C) 2010-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 Meetings
class MenusController < ApplicationController
before_action :load_and_authorize_in_optional_project

def show
@submenu_menu_items = ::Meetings::Menu.new(project: @project, params:).menu_items
@create_btn_options = if @project.present? && User.current.allowed_in_project?(:create_meetings, @project)
{ href: new_project_meeting_path(@project), module_key: "meeting" }
elsif @project.nil? && User.current.allowed_in_any_project?(:create_meetings)
{ href: new_meeting_path, module_key: "meeting" }
end

render layout: nil
end
end
end
Loading
Loading