Extract PageHeader code into separate components

This commit is contained in:
Henriette Darge
2024-07-16 09:34:16 +02:00
parent 46860150b1
commit 2230cd8a99
27 changed files with 805 additions and 287 deletions
@@ -0,0 +1,71 @@
<%#-- 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.
++#%>
<%=
render(Primer::OpenProject::PageHeader.new) do |header|
header.with_title { @group.name }
header.with_breadcrumbs(breadcrumb_items)
header.with_action_button(tag: :a,
mobile_icon: :person,
mobile_label: t(:label_profile),
size: :medium,
href: show_group_path(@group),
aria: { label: I18n.t(:label_profile) },
title: I18n.t(:label_profile)) do |button|
button.with_leading_visual_icon(icon: :person)
t(:label_profile)
end
if @current_user.admin?
header.with_action_button(tag: :a,
scheme: :danger,
mobile_icon: :trash,
mobile_label: t(:button_delete),
size: :medium,
href: group_path(@group),
aria: { label: I18n.t(:button_delete) },
data: {
confirm: t(:text_are_you_sure),
method: :delete,
},
title: I18n.t(:button_delete)) do |button|
button.with_leading_visual_icon(icon: :trash)
t(:button_delete)
end
end
header.with_tab_nav(label: nil) do |tab_nav|
@tabs.each do |tab|
tab_nav.with_tab(selected: selected_tab(@tabs) == tab, href: tab[:path]) do |t|
t.with_text { I18n.t("js.#{tab[:label]}") }
end
end
end if @tabs.present?
end
%>
@@ -0,0 +1,51 @@
# frozen_string_literal: true
# -- copyright
# OpenProject is an open source project management software.
# 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.
#
# 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 Groups
class EditPageHeaderComponent < ApplicationComponent
include OpPrimer::ComponentHelpers
include ApplicationHelper
include TabsHelper
def initialize(group:, current_user:, tabs: nil)
super
@group = group
@tabs = tabs
@current_user = current_user
end
def breadcrumb_items
[{ href: admin_index_path, text: t("label_administration") },
{ href: admin_settings_users_path, text: t(:label_user_and_permission) },
{ href: groups_path, text: t(:label_group_plural) },
@group.name]
end
end
end
@@ -0,0 +1,64 @@
<%#-- 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.
++#%>
<%=
render(Primer::OpenProject::PageHeader.new) do |header|
header.with_title(test_selector: "groups--title") { @group.name }
header.with_breadcrumbs(breadcrumb_items)
if @current_user.admin?
header.with_action_button(tag: :a,
mobile_icon: :pencil,
mobile_label: t(:button_edit),
size: :medium,
href: edit_group_path(@group),
aria: { label: I18n.t(:button_edit) },
data: { "test-selector": "groups--edit-group-button" },
title: I18n.t(:button_edit)) do |button|
button.with_leading_visual_icon(icon: :pencil)
t(:button_edit)
end
header.with_action_button(tag: :a,
scheme: :danger,
mobile_icon: :trash,
mobile_label: t(:button_delete),
size: :medium,
href: group_path(@group),
aria: { label: I18n.t(:button_delete) },
data: {
confirm: t(:text_are_you_sure),
method: :delete,
},
title: I18n.t(:button_delete)) do |button|
button.with_leading_visual_icon(icon: :trash)
t(:button_delete)
end
end
end
%>
@@ -0,0 +1,47 @@
# frozen_string_literal: true
# -- copyright
# OpenProject is an open source project management software.
# 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.
#
# 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 Groups
class ShowPageHeaderComponent < ApplicationComponent
include OpPrimer::ComponentHelpers
include ApplicationHelper
def initialize(group:, current_user:)
super
@group = group
@current_user = current_user
end
def breadcrumb_items
[{ href: groups_path, text: t(:label_group_plural) },
@group.name]
end
end
end
@@ -26,18 +26,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
See COPYRIGHT and LICENSE files for more details.
++#%>
<% title = @placeholder_user.new_record? ? t(:label_placeholder_user_new) : @placeholder_user.name %>
<% deletable = can_delete_placeholder_user?(@placeholder_user) %>
<%=
render(Primer::OpenProject::PageHeader.new) do |header|
header.with_title { title }
header.with_breadcrumbs([{ href: admin_index_path, text: t("label_administration") },
{ href: admin_settings_users_path, text: t(:label_user_and_permission) },
{ href: placeholder_users_path, text: t(:label_placeholder_user_plural) },
title])
header.with_breadcrumbs(breadcrumb_items)
unless @placeholder_user.new_record?
unless new_record?
header.with_action_button(tag: :a,
mobile_icon: :person,
mobile_label: t(:label_profile),
@@ -54,24 +49,22 @@ See COPYRIGHT and LICENSE files for more details.
mobile_icon: :trash,
mobile_label: t(:button_delete),
size: :medium,
disabled: !deletable,
href: deletable ? deletion_info_placeholder_user_path(@placeholder_user) : "#",
disabled: !deletable?,
href: delete_button_href,
aria: { label: I18n.t(:button_delete) },
data: { "test-selector": "placeholder-user--delete-button" },
title: deletable ?
I18n.t(:button_delete) :
I18n.t("placeholder_users.right_to_manage_members_missing")) do |button|
title: delete_button_title) do |button|
button.with_leading_visual_icon(icon: :trash)
t(:button_delete)
end
end
header.with_tab_nav(label: nil) do |tab_nav|
tabs.each do |tab|
tab_nav.with_tab(selected: selected_tab(tabs) == tab, href: tab[:path]) do |t|
@tabs.each do |tab|
tab_nav.with_tab(selected: selected_tab(@tabs) == tab, href: tab[:path]) do |t|
t.with_text { I18n.t("js.#{tab[:label]}") }
end
end
end if tabs.present?
end if @tabs.present?
end
%>
@@ -0,0 +1,79 @@
# frozen_string_literal: true
# -- copyright
# OpenProject is an open source project management software.
# 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.
#
# 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 PlaceholderUsers
class EditPageHeaderComponent < ApplicationComponent
include OpPrimer::ComponentHelpers
include ApplicationHelper
include TabsHelper
include PlaceholderUsersHelper
def initialize(placeholder_user:, tabs: nil)
super
@placeholder_user = placeholder_user
@tabs = tabs
end
def breadcrumb_items
[{ href: admin_index_path, text: t("label_administration") },
{ href: admin_settings_users_path, text: t(:label_user_and_permission) },
{ href: placeholder_users_path, text: t(:label_placeholder_user_plural) },
title]
end
def new_record?
@placeholder_user.new_record?
end
def title
new_record? ? t(:label_placeholder_user_new) : @placeholder_user.name
end
def deletable?
can_delete_placeholder_user?(@placeholder_user)
end
def delete_button_href
if deletable?
deletion_info_placeholder_user_path(@placeholder_user)
else
"#"
end
end
def delete_button_title
if deletable?
I18n.t(:button_delete)
else
I18n.t("placeholder_users.right_to_manage_members_missing")
end
end
end
end
@@ -0,0 +1,62 @@
<%#-- 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.
++#%>
<%=
render(Primer::OpenProject::PageHeader.new) do |header|
header.with_title { "#{avatar @placeholder_user} #{h(@placeholder_user.name)}".html_safe }
header.with_breadcrumbs(breadcrumb_items)
if @current_user.allowed_globally?(:manage_placeholder_user)
header.with_action_button(tag: :a,
mobile_icon: :pencil,
mobile_label: t(:button_edit),
size: :medium,
accesskey: accesskey(:edit),
href: edit_placeholder_user_path(@placeholder_user),
aria: { label: I18n.t(:button_edit) },
title: I18n.t(:button_edit)) do |button|
button.with_leading_visual_icon(icon: :pencil)
t(:button_edit)
end
end
header.with_action_button(tag: :a,
scheme: :danger,
mobile_icon: :trash,
mobile_label: t(:button_delete),
size: :medium,
disabled: !deletable?,
href: delete_button_href,
aria: { label: I18n.t(:button_delete) },
data: { "test-selector": "placeholder-user--delete-button" },
title: delete_button_title) do |button|
button.with_leading_visual_icon(icon: :trash)
t(:button_delete)
end
end
%>
@@ -0,0 +1,71 @@
# frozen_string_literal: true
# -- copyright
# OpenProject is an open source project management software.
# 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.
#
# 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 PlaceholderUsers
class ShowPageHeaderComponent < ApplicationComponent
include OpPrimer::ComponentHelpers
include ApplicationHelper
include PlaceholderUsersHelper
include AvatarHelper
def initialize(placeholder_user:, current_user:)
super
@placeholder_user = placeholder_user
@current_user = current_user
end
def breadcrumb_items
[
{ href: placeholder_user_path, text: t(:label_placeholder_user_plural) },
@placeholder_user.name
]
end
def deletable?
can_delete_placeholder_user?(@placeholder_user)
end
def delete_button_href
if deletable?
deletion_info_placeholder_user_path(@placeholder_user)
else
"#"
end
end
def delete_button_title
if deletable?
I18n.t(:button_delete)
else
I18n.t("placeholder_users.right_to_manage_members_missing")
end
end
end
end
@@ -29,10 +29,7 @@ See COPYRIGHT and LICENSE files for more details.
<%=
render(Primer::OpenProject::PageHeader.new) do |header|
header.with_title { @user.name }
header.with_breadcrumbs([{ href: admin_index_path, text: t("label_administration") },
{ href: admin_settings_users_path, text: t(:label_user_and_permission) },
{ href: users_path, text: t(:label_user_plural) },
@user.name])
header.with_breadcrumbs(breadcrumb_items)
header.with_action_button(tag: :a,
mobile_icon: :person,
@@ -45,7 +42,7 @@ See COPYRIGHT and LICENSE files for more details.
t(:label_profile)
end
if current_user.allowed_globally?(:create_user)
if @current_user.allowed_globally?(:create_user)
header.with_action_button(tag: :a,
mobile_icon: :mail,
mobile_label: t(:label_send_invitation),
@@ -59,8 +56,8 @@ See COPYRIGHT and LICENSE files for more details.
end
end
if current_user.admin?
unless current_user.id == @user.id
if @current_user.admin?
unless @current_user.id == @user.id
iterate_user_statusses(@user) do |title, name|
header.with_action_button(tag: :a,
mobile_icon: change_user_status_icons[name],
@@ -93,11 +90,11 @@ See COPYRIGHT and LICENSE files for more details.
end
header.with_tab_nav(label: nil) do |tab_nav|
tabs.each do |tab|
tab_nav.with_tab(selected: selected_tab(tabs) == tab, href: tab[:path]) do |t|
@tabs.each do |tab|
tab_nav.with_tab(selected: selected_tab(@tabs) == tab, href: tab[:path]) do |t|
t.with_text { I18n.t("js.#{tab[:label]}") }
end
end
end if tabs.present?
end if @tabs.present?
end
%>
@@ -0,0 +1,50 @@
# frozen_string_literal: true
# -- copyright
# OpenProject is an open source project management software.
# 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.
#
# 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.
# ++
class Users::EditPageHeaderComponent < ApplicationComponent
include OpPrimer::ComponentHelpers
include ApplicationHelper
include TabsHelper
include UsersHelper
def initialize(user:, current_user:, tabs: nil)
super
@user = user
@tabs = tabs
@current_user = current_user
end
def breadcrumb_items
[{ href: admin_index_path, text: t("label_administration") },
{ href: admin_settings_users_path, text: t(:label_user_and_permission) },
{ href: users_path, text: t(:label_user_plural) },
@user.name]
end
end
@@ -0,0 +1,14 @@
<%=
render(Primer::OpenProject::PageHeader.new) do |header|
header.with_title { t(:label_user_plural) }
header.with_breadcrumbs(breadcrumb_items)
header.with_description do %>
<%= t(:label_enterprise_active_users, current: OpenProject::Enterprise.active_user_count, limit: user_limit) %>
&nbsp;
<%= render(Primer::Beta::Button.new(scheme: :primary,
size: :small,
tag: :a,
href: OpenProject::Enterprise.upgrade_path,
title: t(:title_enterprise_upgrade))) { t(:button_upgrade) } %>
<% end if user_limit %>
<% end %>
@@ -0,0 +1,47 @@
# frozen_string_literal: true
# -- copyright
# OpenProject is an open source project management software.
# 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.
#
# 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.
# ++
class Users::IndexPageHeaderComponent < ApplicationComponent
include OpPrimer::ComponentHelpers
include ApplicationHelper
def breadcrumb_items
[{ href: admin_index_path, text: t("label_administration") },
{ href: admin_settings_users_path, text: t(:label_user_and_permission) },
t(:label_user_plural)]
end
def user_limit
token = OpenProject::Enterprise.token
limit = token && Hash(token.restrictions)[:active_user_count]
limit if limit && limit > 0
end
end
@@ -0,0 +1,16 @@
<%=
render(Primer::OpenProject::SubHeader.new) do |subheader|
subheader.with_action_button(scheme: :primary,
aria: { label: I18n.t(:label_user_new) },
title: I18n.t(:label_user_new),
tag: :a,
href: new_user_path) do |button|
button.with_leading_visual_icon(icon: :plus)
t('activerecord.models.user')
end
subheader.with_bottom_pane_component do
render Users::UserFilterComponent.new(@params, groups: @groups, status: @status)
end
end
%>
@@ -0,0 +1,42 @@
# frozen_string_literal: true
# -- copyright
# OpenProject is an open source project management software.
# 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.
#
# 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 Users
class IndexSubHeaderComponent < ApplicationComponent
include ApplicationHelper
def initialize(groups:, status:, params:)
super
@groups = groups
@status = status
@params = params
end
end
end
@@ -0,0 +1,61 @@
<%#-- 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.
++#%>
<%=
render(Primer::OpenProject::PageHeader.new) do |header|
header.with_title { "#{avatar @user} #{h(@user.name)}".html_safe }
header.with_breadcrumbs(breadcrumb_items)
if @current_user.allowed_globally?(:manage_user)
header.with_action_button(tag: :a,
mobile_icon: :pencil,
mobile_label: t(:button_edit),
size: :medium,
href: edit_user_path(@user),
aria: { label: I18n.t(:button_edit) },
title: I18n.t(:button_edit)) do |button|
button.with_leading_visual_icon(icon: :pencil)
t(:button_edit)
end
end
if @current_user.allowed_globally?(:create_user) && @current_user != @user
header.with_action_button(tag: :a,
mobile_icon: :mail,
mobile_label: t(:label_send_invitation),
size: :medium,
href: resend_invitation_user_path(@user),
data: { method: :post },
aria: { label: I18n.t(:label_send_invitation) },
title: I18n.t(:tooltip_resend_invitation)) do |button|
button.with_leading_visual_icon(icon: :mail)
t(:label_send_invitation)
end
end
end
%>
@@ -0,0 +1,46 @@
# frozen_string_literal: true
# -- copyright
# OpenProject is an open source project management software.
# 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.
#
# 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.
# ++
class Users::ShowPageHeaderComponent < ApplicationComponent
include OpPrimer::ComponentHelpers
include ApplicationHelper
include AvatarHelper
def initialize(user:, current_user:)
super
@user = user
@current_user = current_user
end
def breadcrumb_items
[{ href: users_path, text: t(:label_user_plural) },
@user.name]
end
end
+1 -1
View File
@@ -89,7 +89,7 @@ module UsersHelper
def build_change_user_status_action(user)
result = "".html_safe
iterate_user_statusses(user) do |title, name|
result << ((yield title, name) + " ".html_safe)
result << ((yield title, name) + " ") # rubocop:disable Style/StringConcatenation
end
result
end
+1 -46
View File
@@ -31,51 +31,6 @@ See COPYRIGHT and LICENSE files for more details.
<% tabs = group_settings_tabs(@group) %>
<%=
render(Primer::OpenProject::PageHeader.new) do |header|
header.with_title { @group.name }
header.with_breadcrumbs([{ href: admin_index_path, text: t("label_administration") },
{ href: admin_settings_users_path, text: t(:label_user_and_permission) },
{ href: groups_path, text: t(:label_group_plural) },
@group.name])
header.with_action_button(tag: :a,
mobile_icon: :person,
mobile_label: t(:label_profile),
size: :medium,
href: show_group_path(@group),
aria: { label: I18n.t(:label_profile) },
title: I18n.t(:label_profile)) do |button|
button.with_leading_visual_icon(icon: :person)
t(:label_profile)
end
if current_user.admin?
header.with_action_button(tag: :a,
scheme: :danger,
mobile_icon: :trash,
mobile_label: t(:button_delete),
size: :medium,
href: group_path(@group),
aria: { label: I18n.t(:button_delete) },
data: {
confirm: t(:text_are_you_sure),
method: :delete,
},
title: I18n.t(:button_delete)) do |button|
button.with_leading_visual_icon(icon: :trash)
t(:button_delete)
end
end
header.with_tab_nav(label: nil) do |tab_nav|
tabs.each do |tab|
tab_nav.with_tab(selected: selected_tab(tabs) == tab, href: tab[:path]) do |t|
t.with_text { I18n.t("js.#{tab[:label]}") }
end
end
end if tabs.present?
end
%>
<%= render Groups::EditPageHeaderComponent.new(group: @group, current_user:, tabs: tabs) %>
<%= render_tabs tabs, with_tab_nav: false %>
+1 -40
View File
@@ -28,46 +28,7 @@ See COPYRIGHT and LICENSE files for more details.
++#%>
<% html_title h(@group.name), t(:label_group_plural) -%>
<%=
render(Primer::OpenProject::PageHeader.new) do |header|
header.with_title(test_selector: "groups--title") { @group.name }
header.with_breadcrumbs(
[
{ href: groups_path, text: t(:label_group_plural) },
@group.name
])
if current_user.admin?
header.with_action_button(tag: :a,
mobile_icon: :pencil,
mobile_label: t(:button_edit),
size: :medium,
href: edit_group_path(@group),
aria: { label: I18n.t(:button_edit) },
data: { "test-selector": "groups--edit-group-button" },
title: I18n.t(:button_edit)) do |button|
button.with_leading_visual_icon(icon: :pencil)
t(:button_edit)
end
header.with_action_button(tag: :a,
scheme: :danger,
mobile_icon: :trash,
mobile_label: t(:button_delete),
size: :medium,
href: group_path(@group),
aria: { label: I18n.t(:button_delete) },
data: {
confirm: t(:text_are_you_sure),
method: :delete,
},
title: I18n.t(:button_delete)) do |button|
button.with_leading_visual_icon(icon: :trash)
t(:button_delete)
end
end
end
%>
<%= render Groups::ShowPageHeaderComponent.new(group: @group, current_user:) %>
<% if @group_users.any? %>
<ul>
@@ -1,48 +0,0 @@
<%#-- 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.
++#%>
<% if can_delete_placeholder_user?(@placeholder_user) %>
<li class="toolbar-item">
<%= link_to deletion_info_placeholder_user_path(@placeholder_user),
class: 'button' do %>
<%= op_icon('button--icon icon-delete') %>
<span class="button--text"><%= t(:button_delete) %></span>
<% end %>
</li>
<% else %>
<li class="toolbar-item">
<%= content_tag :span, title: I18n.t('placeholder_users.right_to_manage_members_missing') do %>
<%= link_to '#',
class: 'button -disabled' do %>
<%= op_icon('button--icon icon-delete') %>
<span class="button--text"><%= t(:button_delete) %></span>
<% end %>
<% end %>
</li>
<% end %>
+1 -1
View File
@@ -32,6 +32,6 @@ See COPYRIGHT and LICENSE files for more details.
<% tabs = tabs_for_key(:placeholder_user, placeholder_user: @placeholder_user) %>
<%= render partial: 'toolbar', locals: { tabs: tabs } %>
<%= render PlaceholderUsers::EditPageHeaderComponent.new(placeholder_user: @placeholder_user, tabs: tabs) %>
<%= render_tabs tabs, with_tab_nav: false %>
+1 -2
View File
@@ -28,9 +28,8 @@ See COPYRIGHT and LICENSE files for more details.
++#%>
<% html_title t(:label_administration), t("label_placeholder_user_new") %>
<% local_assigns[:additional_breadcrumb] = t(:label_placeholder_user_new) %>
<%= render partial: 'toolbar', locals: { tabs: nil } %>
<%= render PlaceholderUsers::EditPageHeaderComponent.new(placeholder_user: @placeholder_user) %>
<%= labelled_tabular_form_for @placeholder_user,
url: { action: "create" },
+2 -44
View File
@@ -30,49 +30,9 @@ See COPYRIGHT and LICENSE files for more details.
<% content_for :header_tags do %>
<%= call_hook :placeholder_users_show_head %>
<% end %>
<% html_title t(:label_administration), t(:label_placeholder_user_plural) -%>
<% html_title h(@placeholder_user.name) %>
<% deletable = can_delete_placeholder_user?(@placeholder_user) %>
<%=
render(Primer::OpenProject::PageHeader.new) do |header|
header.with_title { "#{avatar @placeholder_user} #{h(@placeholder_user.name)}".html_safe }
header.with_breadcrumbs(
[
{ href: placeholder_user_path, text: t(:label_placeholder_user_plural) },
@placeholder_user.name
])
if current_user.allowed_globally?(:manage_placeholder_user)
header.with_action_button(tag: :a,
mobile_icon: :pencil,
mobile_label: t(:button_edit),
size: :medium,
accesskey: accesskey(:edit),
href: edit_placeholder_user_path(@placeholder_user),
aria: { label: I18n.t(:button_edit) },
title: I18n.t(:button_edit)) do |button|
button.with_leading_visual_icon(icon: :pencil)
t(:button_edit)
end
end
header.with_action_button(tag: :a,
scheme: :danger,
mobile_icon: :trash,
mobile_label: t(:button_delete),
size: :medium,
disabled: !deletable,
href: deletable ? deletion_info_placeholder_user_path(@placeholder_user) : "#",
aria: { label: I18n.t(:button_delete) },
data: { "test-selector": "placeholder-user--delete-button" },
title: deletable ?
I18n.t(:button_delete) :
I18n.t("placeholder_users.right_to_manage_members_missing")) do |button|
button.with_leading_visual_icon(icon: :trash)
t(:button_delete)
end
end
%>
<%= render PlaceholderUsers::ShowPageHeaderComponent.new(placeholder_user: @placeholder_user, current_user:) %>
<div class="grid-block grid-block_double-column">
<div class="grid-content">
@@ -94,5 +54,3 @@ See COPYRIGHT and LICENSE files for more details.
<%= call_hook :view_account_left_bottom, placeholder_user: @placeholder_user %>
</div>
</div>
<% html_title h(@placeholder_user.name) %>
+1 -1
View File
@@ -32,6 +32,6 @@ See COPYRIGHT and LICENSE files for more details.
<% tabs = tabs_for_key(:user, user: @user) %>
<%= render partial: 'toolbar', locals: { tabs: tabs } %>
<%= render Users::EditPageHeaderComponent.new(user: @user, current_user:, tabs: tabs) %>
<%= render_tabs tabs, with_tab_nav: false %>
+2 -42
View File
@@ -27,49 +27,9 @@ See COPYRIGHT and LICENSE files for more details.
++#%>
<% html_title t(:label_administration), t(:label_user_plural) -%>
<%
user_limit = begin
token = OpenProject::Enterprise.token
limit = token && Hash(token.restrictions)[:active_user_count]
limit if limit && limit > 0
end
%>
<% users_info = user_limit && content_tag(:div) do %>
<%= t(:label_enterprise_active_users, current: OpenProject::Enterprise.active_user_count, limit: user_limit) %>
&nbsp;
<%= render(Primer::Beta::Button.new(scheme: :primary,
size: :small,
tag: :a,
href: OpenProject::Enterprise.upgrade_path,
title: t(:title_enterprise_upgrade))) { t(:button_upgrade) } %>
<% end %>
<%= render Users::IndexPageHeaderComponent.new %>
<%=
render(Primer::OpenProject::PageHeader.new) do |header|
header.with_title { t(:label_user_plural) }
header.with_breadcrumbs([{ href: admin_index_path, text: t("label_administration") },
{ href: admin_settings_users_path, text: t(:label_user_and_permission) },
t(:label_user_plural)])
header.with_description { users_info } if user_limit
end
%>
<%= render Users::IndexSubHeaderComponent.new(groups: @groups, status: @status, params: params) %>
<%=
render(Primer::OpenProject::SubHeader.new) do |subheader|
subheader.with_action_button(scheme: :primary,
aria: { label: I18n.t(:label_user_new) },
title: I18n.t(:label_user_new),
tag: :a,
href: new_user_path) do |button|
button.with_leading_visual_icon(icon: :plus)
t('activerecord.models.user')
end
subheader.with_bottom_pane_component do
render Users::UserFilterComponent.new(params, groups: @groups, status: @status)
end
end
%>
&nbsp;
<%= render Users::TableComponent.new(rows: @users, current_user: ) %>
+1 -37
View File
@@ -33,42 +33,6 @@ See COPYRIGHT and LICENSE files for more details.
<% html_title h(@user.name), t(:label_user_plural) -%>
<%=
render(Primer::OpenProject::PageHeader.new) do |header|
header.with_title { "#{avatar @user} #{h(@user.name)}".html_safe }
header.with_breadcrumbs(
[
{ href: users_path, text: t(:label_user_plural) },
@user.name
])
if current_user.allowed_globally?(:manage_user)
header.with_action_button(tag: :a,
mobile_icon: :pencil,
mobile_label: t(:button_edit),
size: :medium,
href: edit_user_path(@user),
aria: { label: I18n.t(:button_edit) },
title: I18n.t(:button_edit)) do |button|
button.with_leading_visual_icon(icon: :pencil)
t(:button_edit)
end
end
if current_user.allowed_globally?(:create_user) && current_user != @user
header.with_action_button(tag: :a,
mobile_icon: :mail,
mobile_label: t(:label_send_invitation),
size: :medium,
href: resend_invitation_user_path(@user),
data: { method: :post },
aria: { label: I18n.t(:label_send_invitation) },
title: I18n.t(:tooltip_resend_invitation)) do |button|
button.with_leading_visual_icon(icon: :mail)
t(:label_send_invitation)
end
end
end
%>
<%= render Users::ShowPageHeaderComponent.new(user: @user, current_user:) %>
<%= render Users::ProfileComponent.new(user: @user) %>
@@ -71,3 +71,61 @@ The PageHeader actions offer a set of predefined slots, to use specific componen
* The button will collapse on mobile into the mobile action menu. Therefore, an additional `mobile_label`, as well as a `mobile_label` have to passed.
* **Primer::Beta::Text** ([`with_action_text`](../../inspect/primer/open_project/page_header/actions)):
* The text will be hidden on mobile.
### Code structure
The PageHeader can be called directly in any `show`/`edit`/`index`/... `.html.erb` file.
```html
<!-- app/views/module_a/index.html.erb -->
&lt;%=
render(Primer::OpenProject::PageHeader.new) do |header|
header.with_title { "Some title" }
header.with_breadcrumbs([{ href: "/foo", text: "Foo" },
"Bar"])
end
%&gt;
```
As soon as the header is more complex, it is recommended to extract it into a separate component. A good rule of thumb is to extract the PageHeader as soon as there are actions involved, because it will increase the component code significantly.
```rb
class ModuleA::IndexPageHeaderComponent < ApplicationComponent
include OpPrimer::ComponentHelpers
include ApplicationHelper
def initialize
super
# ...
end
def breadcrumb_items
[{ href: "/foo", text: "Foo" },
"Bar"]
end
def additional_logic
# ...
end
# ...
end
```
```html
<!-- app/components/module_a/index_page_header_component.html.erb -->
&lt;%=
render(Primer::OpenProject::PageHeader.new) do |header|
header.with_title { 'Some title' }
header.with_breadcrumbs(breadcrumb_items)
#... additional logic
end
%&gt;
```
```html
<!-- app/views/module_a/index.html.erb -->
&lt;%= render(ModuleA::IndexPageHeaderComponent.new) %&gt;
```