From 461e620693e539be1a8b0bf5c8600c9913191de0 Mon Sep 17 00:00:00 2001 From: Henriette Darge Date: Mon, 8 Jul 2024 13:47:09 +0200 Subject: [PATCH 01/11] Introduce PageHeader component in Administration / User settings --- .../admin/settings/users_settings_controller.rb | 6 +----- app/views/admin/settings/users_settings/show.html.erb | 9 ++++++++- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/app/controllers/admin/settings/users_settings_controller.rb b/app/controllers/admin/settings/users_settings_controller.rb index 8fb79712df0a..0f081595191f 100644 --- a/app/controllers/admin/settings/users_settings_controller.rb +++ b/app/controllers/admin/settings/users_settings_controller.rb @@ -37,12 +37,8 @@ def show respond_to :html end - def default_breadcrumb - t(:label_user_settings) - end - def show_local_breadcrumb - true + false end def settings_params diff --git a/app/views/admin/settings/users_settings/show.html.erb b/app/views/admin/settings/users_settings/show.html.erb index 28359cedad8e..c412fd7b730b 100644 --- a/app/views/admin/settings/users_settings/show.html.erb +++ b/app/views/admin/settings/users_settings/show.html.erb @@ -28,7 +28,14 @@ See COPYRIGHT and LICENSE files for more details. ++#%> <% html_title t(:label_administration), t(:label_user_settings) -%> -<%= toolbar title: t(:label_user_settings) %> +<%= + render(Primer::OpenProject::PageHeader.new) do |header| + header.with_title { t(:label_user_settings) } + 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_settings)]) + end +%> <%= styled_form_tag(admin_settings_users_path, method: :patch, class: 'admin-settings--form') do %> From 0fc94fa9e872f6ab2f309e511cdfb365d764bc12 Mon Sep 17 00:00:00 2001 From: Henriette Darge Date: Mon, 8 Jul 2024 13:47:45 +0200 Subject: [PATCH 02/11] Introduce PageHeader in Administration / Users --- app/controllers/users_controller.rb | 10 +-- app/helpers/users_helper.rb | 40 +++++++---- app/views/users/_toolbar.html.erb | 106 ++++++++++++++++++---------- app/views/users/edit.html.erb | 1 - app/views/users/index.html.erb | 45 ++++++++---- app/views/users/new.html.erb | 12 +++- app/views/users/show.html.erb | 4 +- 7 files changed, 136 insertions(+), 82 deletions(-) diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 399fab97ab08..4e31de0aa5a7 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -282,16 +282,8 @@ def set_password?(params) protected - def default_breadcrumb - if action_name == "index" - t("label_user_plural") - else - ActionController::Base.helpers.link_to(t("label_user_plural"), users_path) - end - end - def show_local_breadcrumb - can_manage_or_create_users? && action_name != "show" + false end def build_user_update_params diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb index 9c79821c750b..9e1eeaf10c28 100644 --- a/app/helpers/users_helper.rb +++ b/app/helpers/users_helper.rb @@ -87,41 +87,51 @@ def full_user_status(user, include_num_failed_logins = false) # Create buttons to lock/unlock a user and reset failed logins def build_change_user_status_action(user) + result = "".html_safe + iterate_user_statusses(user) do |title, name| + result << ((yield title, name) + " ".html_safe) + end + result + end + + def iterate_user_statusses(user) status = user.status.to_sym blocked = !!user.failed_too_many_recent_login_attempts? - result = "".html_safe (STATUS_CHANGE_ACTIONS[[status, blocked]] || []).each do |title, name| - result << ((yield I18n.t(title, scope: :user), name) + " ".html_safe) + yield I18n.t(title, scope: :user), name end - result end def change_user_status_icons { - "unlock" => "unlocked", - "activate" => "unlocked", - "lock" => "locked" + "unlock" => "unlock", + "activate" => "unlock", + "lock" => "lock" } end def change_user_status_buttons(user) build_change_user_status_action(user) do |title, name| - button_tag(class: "button", name:, type: "submit", title:) do - concat op_icon("button--icon icon-#{change_user_status_icons[name]}") - concat content_tag(:span, title, class: "button--text") + Primer::Beta::Button.new(name:, type: :submit, title:) do |button| + button.with_leading_visual_icon(icon: change_user_status_icons[name]) + title end end end def change_user_status_links(user) build_change_user_status_action(user) do |title, name| - link_to title, - change_status_user_path(user, - name.to_sym => "1", - back_url: request.fullpath), - method: :post, - class: "icon icon-#{change_user_status_icons[name]}" + render Primer::Beta::Button.new(tag: :a, + scheme: :link, + title:, + href: change_status_user_path(user, + name.to_sym => "1", + back_url: request.fullpath), + method: :post) do |button| + button.with_leading_visual_icon(icon: change_user_status_icons[name]) + title + end end end diff --git a/app/views/users/_toolbar.html.erb b/app/views/users/_toolbar.html.erb index 1f6b49fad534..4d6dd0665a62 100644 --- a/app/views/users/_toolbar.html.erb +++ b/app/views/users/_toolbar.html.erb @@ -26,42 +26,70 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. See COPYRIGHT and LICENSE files for more details. ++#%> -<%= breadcrumb_toolbar(@user.name) do %> -
  • - <%= link_to user_path(@user), class: 'button' do %> - <%= op_icon('button--icon icon-user') %> - <%= t(:label_profile) %> - <% end %> -
  • - <% if current_user.allowed_globally?(:create_user) %> -
  • - <%= form_for(@user, - url: { action: :resend_invitation }, - method: :post) do |_form| %> - - <% end %> -
  • - <% end %> - <% if current_user.admin? %> - <% unless current_user.id == @user.id %> -
  • - <%= form_for @user, - :url => { :action => :change_status }, - :method => :post do %> - <%= change_user_status_buttons(@user) %> - <% end %> -
  • - <% end %> - <% if Setting.users_deletable_by_admins? %> -
  • - <%= link_to deletion_info_user_path(@user), class: 'button' do %> - <%= op_icon('button--icon icon-delete') %> - <%= t(:button_delete) %> - <% end %> -
  • - <% end %> - <% end %> -<% end %> +<%= + 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_action_button(tag: :a, + mobile_icon: :person, + mobile_label: t(:label_profile), + size: :medium, + href: user_path(@user), + 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.allowed_globally?(:create_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 + + 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], + mobile_label: title, + size: :medium, + name: name, + href: change_status_user_path(@user, { name => '' }), + data: { method: :post }, + aria: { label: title }, + title: title) do |button| + button.with_leading_visual_icon(icon: change_user_status_icons[name]) + title + end + end + end + + if Setting.users_deletable_by_admins? + header.with_action_button(tag: :a, + scheme: :danger, + mobile_icon: :trash, + mobile_label: t(:button_delete), + size: :medium, + href: deletion_info_user_path(@user), + aria: { label: I18n.t(:button_delete) }, + title: I18n.t(:button_delete)) do |button| + button.with_leading_visual_icon(icon: :trash) + t(:button_delete) + end + end + end + end +%> diff --git a/app/views/users/edit.html.erb b/app/views/users/edit.html.erb index a89e67987723..37666bcc3768 100644 --- a/app/views/users/edit.html.erb +++ b/app/views/users/edit.html.erb @@ -30,7 +30,6 @@ See COPYRIGHT and LICENSE files for more details. <% html_title(t(:label_administration), "#{t(:label_edit)} #{User.model_name.human} #{h(@user.name)}") -%> -<% local_assigns[:additional_breadcrumb] = @user.name %> <%= render partial: 'toolbar', locals: { new_user: false } %> <%= render_extensible_tabs :user, user: @user %> diff --git a/app/views/users/index.html.erb b/app/views/users/index.html.erb index 0e5b25f666bf..1f771901ec00 100644 --- a/app/views/users/index.html.erb +++ b/app/views/users/index.html.erb @@ -38,21 +38,38 @@ See COPYRIGHT and LICENSE files for more details. <% users_info = user_limit && content_tag(:div) do %> <%= t(:label_enterprise_active_users, current: OpenProject::Enterprise.active_user_count, limit: user_limit) %>   - <%= t(:button_upgrade) %> -<% end %> -<%= toolbar title: t(:label_user_plural), title_class: 'no-padding-bottom', subtitle: users_info do %> -
  • - <%= link_to new_user_path, - { class: 'button -primary', - aria: { label: t(:label_user_new) }, - title: t(:label_user_new) } do %> - <%= op_icon('button--icon icon-add') %> - <%= t('activerecord.models.user') %> - <% end %> -
  • - <%= call_hook(:user_admin_action_menu) %> + <%= 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::UserFilterComponent.new(params, groups: @groups, status: @status) %> +<%= + 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(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 +%>   <%= render Users::TableComponent.new(rows: @users, current_user: ) %> diff --git a/app/views/users/new.html.erb b/app/views/users/new.html.erb index 09a6e9bba2e0..8703e31406d9 100644 --- a/app/views/users/new.html.erb +++ b/app/views/users/new.html.erb @@ -28,9 +28,17 @@ See COPYRIGHT and LICENSE files for more details. ++#%> <% html_title t(:label_administration), t("label_user_new") %> -<% local_assigns[:additional_breadcrumb] = t(:label_user_new) %> -<%= toolbar title: t(:label_user_new) %> + +<%= + render(Primer::OpenProject::PageHeader.new) do |header| + header.with_title { t(:label_user_new) } + 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) }, + t(:label_user_new)]) + end +%> <%= error_messages_for @user %> diff --git a/app/views/users/show.html.erb b/app/views/users/show.html.erb index 1dbf16cc1df8..0ffe38b5f8a3 100644 --- a/app/views/users/show.html.erb +++ b/app/views/users/show.html.erb @@ -39,7 +39,7 @@ See COPYRIGHT and LICENSE files for more details. header.with_breadcrumbs( [ { href: users_path, text: t(:label_user_plural) }, - { href: user_path(@user), text: @user.name } + @user.name ]) if current_user.allowed_globally?(:manage_user) @@ -57,7 +57,7 @@ See COPYRIGHT and LICENSE files for more details. if current_user.allowed_globally?(:create_user) && current_user != @user header.with_action_button(tag: :a, - mobile_icon: :pencil, + mobile_icon: :mail, mobile_label: t(:label_send_invitation), size: :medium, href: resend_invitation_user_path(@user), From f7eccde66a96d1be69f97d2df6ed99b2f365f9c7 Mon Sep 17 00:00:00 2001 From: Henriette Darge Date: Mon, 8 Jul 2024 14:40:49 +0200 Subject: [PATCH 03/11] Introduce PageHeader in Administration / Roles --- app/controllers/admin/settings_controller.rb | 5 +++ app/controllers/roles_controller.rb | 10 +----- app/views/roles/edit.html.erb | 11 +++++-- app/views/roles/index.html.erb | 33 ++++++++++++------- app/views/roles/new.html.erb | 11 +++++-- app/views/roles/report.html.erb | 13 ++++++-- .../controllers/avatars/avatar_controller.rb | 8 +++++ 7 files changed, 65 insertions(+), 26 deletions(-) diff --git a/app/controllers/admin/settings_controller.rb b/app/controllers/admin/settings_controller.rb index c7daac6c37d2..6581a1910fba 100644 --- a/app/controllers/admin/settings_controller.rb +++ b/app/controllers/admin/settings_controller.rb @@ -81,6 +81,11 @@ def default_breadcrumb end end + def breadcrumb_items + [{ href: admin_index_path, text: t("label_administration") }] + end + helper_method :breadcrumb_items + protected def find_plugin diff --git a/app/controllers/roles_controller.rb b/app/controllers/roles_controller.rb index 893c26866539..ecc09f416dac 100644 --- a/app/controllers/roles_controller.rb +++ b/app/controllers/roles_controller.rb @@ -143,16 +143,8 @@ def roles_scope Role.visible.ordered_by_builtin_and_position end - def default_breadcrumb - if action_name == "index" - t("label_role_plural") - else - ActionController::Base.helpers.link_to(t("label_role_plural"), roles_path) - end - end - def show_local_breadcrumb - true + false end def new_params diff --git a/app/views/roles/edit.html.erb b/app/views/roles/edit.html.erb index 039cff632ada..97015ff71a94 100644 --- a/app/views/roles/edit.html.erb +++ b/app/views/roles/edit.html.erb @@ -29,8 +29,15 @@ See COPYRIGHT and LICENSE files for more details. <% html_title t(:label_administration), "#{t(:label_edit)} #{Role.model_name.human} #{@role.name}" %> -<% local_assigns[:additional_breadcrumb] = @role.name %> -<%= breadcrumb_toolbar @role.name %> +<%= + render Primer::OpenProject::PageHeader.new do |header| + header.with_title { @role.name } + header.with_breadcrumbs([{ href: admin_index_path, text: t("label_administration") }, + { href: admin_settings_users_path, text: t(:label_user_and_permission) }, + { href: roles_path, text: t(:label_role_and_permissions) }, + @role.name]) + end +%> <%= labelled_tabular_form_for @role, :url => { :action => 'update' }, :html => {:id => 'role_form'}, :as => :role do |f| %> <%= hidden_field_tag :id, @role.id %> diff --git a/app/views/roles/index.html.erb b/app/views/roles/index.html.erb index 26d4fe75c5a7..2e03178fbcfa 100644 --- a/app/views/roles/index.html.erb +++ b/app/views/roles/index.html.erb @@ -27,17 +27,28 @@ See COPYRIGHT and LICENSE files for more details. ++#%> <% html_title t(:label_administration), t("label_role_plural") %> -<%= toolbar title: Role.model_name.human(count: 2) do %> -
  • - <%= link_to({ action: 'new'}, - { class: 'button -primary', - aria: {label: t(:label_role_new)}, - title: t(:label_role_new)}) do %> - <%= op_icon('button--icon icon-add') %> - <%= Role.model_name.human %> - <% end %> -
  • -<% end %> + +<%= + render Primer::OpenProject::PageHeader.new do |header| + header.with_title { Role.model_name.human(count: 2) } + header.with_breadcrumbs([{ href: admin_index_path, text: t("label_administration") }, + { href: admin_settings_users_path, text: t(:label_user_and_permission) }, + t(:label_role_and_permissions)]) + end +%> + +<%= + render(Primer::OpenProject::SubHeader.new) do |subheader| + subheader.with_action_button(scheme: :primary, + aria: { label: I18n.t(:label_role_new) }, + title: I18n.t(:label_role_new), + tag: :a, + href: new_role_path) do |button| + button.with_leading_visual_icon(icon: :plus) + Role.model_name.human + end + end +%>
    diff --git a/app/views/roles/new.html.erb b/app/views/roles/new.html.erb index 8907c98bcdc1..36309d96853a 100644 --- a/app/views/roles/new.html.erb +++ b/app/views/roles/new.html.erb @@ -29,8 +29,15 @@ See COPYRIGHT and LICENSE files for more details. <% html_title t(:label_administration), t(:label_role_new) %> -<% local_assigns[:additional_breadcrumb] = t(:label_role_new) %> -<%= breadcrumb_toolbar t(:label_role_new) %> +<%= + render Primer::OpenProject::PageHeader.new do |header| + header.with_title { I18n.t(:label_role_new) } + header.with_breadcrumbs([{ href: admin_index_path, text: t("label_administration") }, + { href: admin_settings_users_path, text: t(:label_user_and_permission) }, + { href: roles_path, text: t(:label_role_and_permissions) }, + I18n.t(:label_role_new)]) + end +%> <%= labelled_tabular_form_for @role, :url => { :action => 'create' }, :html => {:id => 'role_form'}, :as => :role do |f| %> <%= render partial: 'form', locals: { f: f, role: @role, roles: @roles } %> diff --git a/app/views/roles/report.html.erb b/app/views/roles/report.html.erb index 0377d2cb95f4..04a9452ba5a1 100644 --- a/app/views/roles/report.html.erb +++ b/app/views/roles/report.html.erb @@ -26,8 +26,17 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. See COPYRIGHT and LICENSE files for more details. ++#%> -<%= breadcrumb_toolbar t(:label_permissions_report) %> -<% local_assigns[:additional_breadcrumb] = t(:label_permissions_report) %> + + +<%= + render Primer::OpenProject::PageHeader.new do |header| + header.with_title { I18n.t(:label_permissions_report) } + header.with_breadcrumbs([{ href: admin_index_path, text: t("label_administration") }, + { href: admin_settings_users_path, text: t(:label_user_and_permission) }, + t(:label_permissions_report)]) + end +%> + <% html_title t(:label_administration), t(:label_permissions_report) %> <% (@calls || []).select(&:failure?).each do |call| %> diff --git a/modules/avatars/app/controllers/avatars/avatar_controller.rb b/modules/avatars/app/controllers/avatars/avatar_controller.rb index e76b67ea3b50..7ebb65ed0048 100644 --- a/modules/avatars/app/controllers/avatars/avatar_controller.rb +++ b/modules/avatars/app/controllers/avatars/avatar_controller.rb @@ -15,6 +15,14 @@ def show head :not_found end + def breadcrumb_items + [{ href: admin_index_path, text: t("label_administration") }, + { href: admin_settings_users_path, text: t(:label_user_settings) }, + @plugin.name] + end + + helper_method :breadcrumb_items + private def find_avatar From 7d4a30fdc5e0e535050d2ceb70a55c4d55b746b6 Mon Sep 17 00:00:00 2001 From: Henriette Darge Date: Mon, 15 Jul 2024 09:39:16 +0200 Subject: [PATCH 04/11] Use tabNav element of the pageHeader in Admin -> Users -> Edit user --- app/helpers/tabs_helper.rb | 8 ++++++-- app/views/users/_notifications.html.erb | 2 +- app/views/users/_reminders.html.erb | 2 +- app/views/users/_toolbar.html.erb | 8 ++++++++ app/views/users/edit.html.erb | 10 ++++++++-- .../page/notifications-settings-page.component.html | 2 +- .../page/notifications-settings-page.component.ts | 2 ++ .../page/reminder-settings-page.component.html | 2 +- .../page/reminder-settings-page.component.ts | 2 ++ .../app/views/avatars/users/_avatar_tab.html.erb | 2 -- modules/costs/app/views/users/_rates.html.erb | 1 - 11 files changed, 30 insertions(+), 11 deletions(-) diff --git a/app/helpers/tabs_helper.rb b/app/helpers/tabs_helper.rb index c7db4c8fd8be..46a130caca49 100644 --- a/app/helpers/tabs_helper.rb +++ b/app/helpers/tabs_helper.rb @@ -43,10 +43,14 @@ def selected_tab(tabs) # Render tabs from the ui/extensible tabs manager def render_extensible_tabs(key, params = {}) - tabs = ::OpenProject::Ui::ExtensibleTabs.enabled_tabs(key, params.reverse_merge(current_user:)).map do |tab| + tabs = tabs_for_key(key, params) + render_tabs(tabs) + end + + def tabs_for_key(key, params = {}) + ::OpenProject::Ui::ExtensibleTabs.enabled_tabs(key, params.reverse_merge(current_user:)).map do |tab| path = tab[:path].respond_to?(:call) ? instance_exec(params, &tab[:path]) : tab[:path] tab.dup.merge(path:) end - render_tabs(tabs) end end diff --git a/app/views/users/_notifications.html.erb b/app/views/users/_notifications.html.erb index 95ad5574eb60..56f4043b3dac 100644 --- a/app/views/users/_notifications.html.erb +++ b/app/views/users/_notifications.html.erb @@ -26,4 +26,4 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. See COPYRIGHT and LICENSE files for more details. ++#%> -<%= angular_component_tag "opce-notification-settings", inputs: { userId: @user.id } %> +<%= angular_component_tag "opce-notification-settings", inputs: { userId: @user.id, showToolbar: false } %> diff --git a/app/views/users/_reminders.html.erb b/app/views/users/_reminders.html.erb index f2f3fc85842c..1d211e2c5d58 100644 --- a/app/views/users/_reminders.html.erb +++ b/app/views/users/_reminders.html.erb @@ -26,4 +26,4 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. See docs/COPYRIGHT.rdoc for more details. ++#%> -<%= angular_component_tag "opce-reminder-settings", inputs: { userId: @user.id } %> +<%= angular_component_tag "opce-reminder-settings", inputs: { userId: @user.id, show_toolbar: false } %> diff --git a/app/views/users/_toolbar.html.erb b/app/views/users/_toolbar.html.erb index 4d6dd0665a62..73f462eaad5e 100644 --- a/app/views/users/_toolbar.html.erb +++ b/app/views/users/_toolbar.html.erb @@ -91,5 +91,13 @@ See COPYRIGHT and LICENSE files for more details. end 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 %> diff --git a/app/views/users/edit.html.erb b/app/views/users/edit.html.erb index 37666bcc3768..209c7fd054bf 100644 --- a/app/views/users/edit.html.erb +++ b/app/views/users/edit.html.erb @@ -30,6 +30,12 @@ See COPYRIGHT and LICENSE files for more details. <% html_title(t(:label_administration), "#{t(:label_edit)} #{User.model_name.human} #{h(@user.name)}") -%> -<%= render partial: 'toolbar', locals: { new_user: false } %> +<% tabs = tabs_for_key(:user, user: @user) %> +<% selected_tab = selected_tab(tabs) %> -<%= render_extensible_tabs :user, user: @user %> +<%= render partial: 'toolbar', locals: { tabs: tabs } %> + +<%= content_tag 'div', + render(partial: selected_tab[:partial], locals: { tab: selected_tab } ), + id: "tab-content-#{selected_tab[:name]}", + class: 'tab-content' %> diff --git a/frontend/src/app/features/user-preferences/notifications-settings/page/notifications-settings-page.component.html b/frontend/src/app/features/user-preferences/notifications-settings/page/notifications-settings-page.component.html index 8b7599913a20..254e4e3593f5 100644 --- a/frontend/src/app/features/user-preferences/notifications-settings/page/notifications-settings-page.component.html +++ b/frontend/src/app/features/user-preferences/notifications-settings/page/notifications-settings-page.component.html @@ -1,4 +1,4 @@ - +
    +

    diff --git a/frontend/src/app/features/user-preferences/reminder-settings/page/reminder-settings-page.component.ts b/frontend/src/app/features/user-preferences/reminder-settings/page/reminder-settings-page.component.ts index 8d271291f78d..e0ad947ee4fe 100644 --- a/frontend/src/app/features/user-preferences/reminder-settings/page/reminder-settings-page.component.ts +++ b/frontend/src/app/features/user-preferences/reminder-settings/page/reminder-settings-page.component.ts @@ -36,6 +36,8 @@ interface IReminderSettingsFormValue { export class ReminderSettingsPageComponent extends UntilDestroyedMixin implements OnInit { @Input() userId:string; + @Input() showToolbar = true; + public form = this.fb.group({ immediateReminders: this.fb.group({ mentioned: this.fb.control(false), diff --git a/modules/avatars/app/views/avatars/users/_avatar_tab.html.erb b/modules/avatars/app/views/avatars/users/_avatar_tab.html.erb index b7803c0d2bb7..344a246dd5a8 100644 --- a/modules/avatars/app/views/avatars/users/_avatar_tab.html.erb +++ b/modules/avatars/app/views/avatars/users/_avatar_tab.html.erb @@ -1,5 +1,3 @@ -

    <%= t(:button_change_avatar) %>

    - <% @manager = ::OpenProject::Avatars::AvatarManager %> <% @target_avatar_path = edit_user_avatar_path(@user) %> <%= form_tag(edit_user_avatar_path(@user), method: :put, name: 'avatar_form', multipart: true) do %> diff --git a/modules/costs/app/views/users/_rates.html.erb b/modules/costs/app/views/users/_rates.html.erb index 65ee2ac1581a..71afdf2aec1f 100644 --- a/modules/costs/app/views/users/_rates.html.erb +++ b/modules/costs/app/views/users/_rates.html.erb @@ -27,7 +27,6 @@ See COPYRIGHT and LICENSE files for more details. ++#%> -

    <%= t(:caption_rate_history) %>

    <% @rates = HourlyRate.history_for_user(@user) @rates_default = @rates.delete(nil) From 4f941dfda091030bf0c015f263bf5cbaa678504c Mon Sep 17 00:00:00 2001 From: Henriette Darge Date: Mon, 15 Jul 2024 10:56:19 +0200 Subject: [PATCH 05/11] Introduce PageHeader component in Administration -> user settings -> Placeholder users --- .../placeholder_users_controller.rb | 11 +--- app/helpers/tabs_helper.rb | 6 -- app/views/placeholder_users/_toolbar.html.erb | 59 +++++++++++++++---- app/views/placeholder_users/edit.html.erb | 11 +++- app/views/placeholder_users/index.html.erb | 41 +++++++------ app/views/placeholder_users/new.html.erb | 5 +- app/views/placeholder_users/show.html.erb | 52 ++++++++++++---- spec/helpers/tabs_helper_spec.rb | 9 +-- 8 files changed, 126 insertions(+), 68 deletions(-) diff --git a/app/controllers/placeholder_users_controller.rb b/app/controllers/placeholder_users_controller.rb index 9936ed290323..e60daf4047f5 100644 --- a/app/controllers/placeholder_users_controller.rb +++ b/app/controllers/placeholder_users_controller.rb @@ -158,16 +158,7 @@ def authorize_deletion end end - def default_breadcrumb - if action_name == "index" - t("label_placeholder_user_plural") - else - ActionController::Base.helpers.link_to(t("label_placeholder_user_plural"), - placeholder_users_path) - end - end - def show_local_breadcrumb - action_name != "show" + false end end diff --git a/app/helpers/tabs_helper.rb b/app/helpers/tabs_helper.rb index 46a130caca49..64370492b4dd 100644 --- a/app/helpers/tabs_helper.rb +++ b/app/helpers/tabs_helper.rb @@ -41,12 +41,6 @@ def selected_tab(tabs) tabs.detect { |t| t[:name] == params[:tab] } || tabs.first end - # Render tabs from the ui/extensible tabs manager - def render_extensible_tabs(key, params = {}) - tabs = tabs_for_key(key, params) - render_tabs(tabs) - end - def tabs_for_key(key, params = {}) ::OpenProject::Ui::ExtensibleTabs.enabled_tabs(key, params.reverse_merge(current_user:)).map do |tab| path = tab[:path].respond_to?(:call) ? instance_exec(params, &tab[:path]) : tab[:path] diff --git a/app/views/placeholder_users/_toolbar.html.erb b/app/views/placeholder_users/_toolbar.html.erb index 47de2c2c7ae8..d969dec61a26 100644 --- a/app/views/placeholder_users/_toolbar.html.erb +++ b/app/views/placeholder_users/_toolbar.html.erb @@ -26,14 +26,51 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. See COPYRIGHT and LICENSE files for more details. ++#%> -<%= breadcrumb_toolbar(@placeholder_user.new_record? ? t(:label_placeholder_user_new) : @placeholder_user.name) do %> - <% unless @placeholder_user.new_record? %> -
  • - <%= link_to placeholder_user_path(@placeholder_user), class: 'button' do %> - <%= op_icon('button--icon icon-user') %> - <%= t(:label_profile) %> - <% end %> -
  • - <%= render partial: 'placeholder_users/toolbar_delete' %> - <% end %> -<% end %> +<% 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]) + + unless @placeholder_user.new_record? + header.with_action_button(tag: :a, + mobile_icon: :person, + mobile_label: t(:label_profile), + size: :medium, + href: placeholder_user_path(@placeholder_user), + aria: { label: I18n.t(:label_profile) }, + title: I18n.t(:label_profile)) do |button| + button.with_leading_visual_icon(icon: :person) + t(:label_profile) + 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) }, + 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 + + 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 +%> diff --git a/app/views/placeholder_users/edit.html.erb b/app/views/placeholder_users/edit.html.erb index ebd3833c0bae..6ddccd074d67 100644 --- a/app/views/placeholder_users/edit.html.erb +++ b/app/views/placeholder_users/edit.html.erb @@ -30,7 +30,12 @@ See COPYRIGHT and LICENSE files for more details. <% html_title(t(:label_administration), "#{t(:label_edit)} #{PlaceholderUser.model_name.human} #{h(@placeholder_user.name)}") -%> -<% local_assigns[:additional_breadcrumb] = @placeholder_user.name %> -<%= render partial: 'toolbar', locals: { new_user: false, :@placeholder_user => @placeholder_user } %> +<% tabs = tabs_for_key(:placeholder_user, placeholder_user: @placeholder_user) %> +<% selected_tab = selected_tab(tabs) %> -<%= render_extensible_tabs :placeholder_user, placeholder_user: @placeholder_user %> +<%= render partial: 'toolbar', locals: { tabs: tabs } %> + +<%= content_tag 'div', + render(partial: selected_tab[:partial], locals: { tab: selected_tab } ), + id: "tab-content-#{selected_tab[:name]}", + class: 'tab-content' %> diff --git a/app/views/placeholder_users/index.html.erb b/app/views/placeholder_users/index.html.erb index 541b8a89ab72..0b65abf905a5 100644 --- a/app/views/placeholder_users/index.html.erb +++ b/app/views/placeholder_users/index.html.erb @@ -29,28 +29,33 @@ See COPYRIGHT and LICENSE files for more details. <% html_title t(:label_administration), t(:label_placeholder_user_plural) -%> <% has_ee = EnterpriseToken.allows_to?(:placeholder_users) %> - <% if has_ee %> - <%= toolbar title: t(:label_placeholder_user_plural), title_class: 'no-padding-bottom' do %> -
  • - <%= link_to new_placeholder_user_path, - { class: 'button -primary', - aria: { label: t(:label_placeholder_user_new) }, - title: t(:label_placeholder_user_new) } do %> - <%= op_icon('button--icon icon-add') %> - <%= t('activerecord.models.placeholder_user') %> - <% end %> -
  • - - <%= call_hook(:placeholder_user_admin_action_menu) %> - <% end %> + <%= + render(Primer::OpenProject::PageHeader.new) do |header| + header.with_title { t(:label_placeholder_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_placeholder_user_plural)]) + end + %> -<% end %> + <%= + render(Primer::OpenProject::SubHeader.new) do |subheader| + subheader.with_action_button(scheme: :primary, + aria: { label: I18n.t(:label_placeholder_user_new) }, + title: I18n.t(:label_placeholder_user_new), + tag: :a, + href: new_placeholder_user_path) do |button| + button.with_leading_visual_icon(icon: :plus) + t('activerecord.models.placeholder_user') + end + subheader.with_bottom_pane_component do + render PlaceholderUsers::PlaceholderUserFilterComponent.new(params) + end + end + %> -<% if has_ee %> - <%= render PlaceholderUsers::PlaceholderUserFilterComponent.new(params) %> -   <%= render PlaceholderUsers::TableComponent.new(rows: @placeholder_users) %> <% else %> <%= render template: 'common/upsale', diff --git a/app/views/placeholder_users/new.html.erb b/app/views/placeholder_users/new.html.erb index b8f1a4e4dffd..821ea8f7c471 100644 --- a/app/views/placeholder_users/new.html.erb +++ b/app/views/placeholder_users/new.html.erb @@ -29,8 +29,9 @@ 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: { new_user: true, - :@placeholder_user => @placeholder_user } %> + +<%= render partial: 'toolbar', locals: { tabs: nil } %> + <%= labelled_tabular_form_for @placeholder_user, url: { action: "create" }, html: { class: nil, autocomplete: 'off' }, diff --git a/app/views/placeholder_users/show.html.erb b/app/views/placeholder_users/show.html.erb index a0f1cad7969b..5fc19af8b283 100644 --- a/app/views/placeholder_users/show.html.erb +++ b/app/views/placeholder_users/show.html.erb @@ -31,17 +31,47 @@ See COPYRIGHT and LICENSE files for more details. <%= call_hook :placeholder_users_show_head %> <% end %> <% html_title t(:label_administration), t(:label_placeholder_user_plural) -%> -<%= toolbar title: "#{avatar @placeholder_user} #{h(@placeholder_user.name)}".html_safe do %> - <% if current_user.allowed_globally?(:manage_placeholder_user) %> -
  • - <%= link_to edit_placeholder_user_path(@placeholder_user), class: 'button', accesskey: accesskey(:edit) do %> - <%= op_icon('button--icon icon-edit') %> - <%= t(:button_edit) %> - <% end %> -
  • - <%= render partial: 'placeholder_users/toolbar_delete' %> - <% end %> -<% end %> + +<% 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) }, + 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 +%>
    diff --git a/spec/helpers/tabs_helper_spec.rb b/spec/helpers/tabs_helper_spec.rb index 72bca4a238dc..9a27e0b89d90 100644 --- a/spec/helpers/tabs_helper_spec.rb +++ b/spec/helpers/tabs_helper_spec.rb @@ -45,16 +45,11 @@ label: :label_avatar } end - describe "render_extensible_tabs" do + describe "tabs_for_key" do let(:current_user) { build(:user) } let(:user) { build(:user, id: 2) } before do - allow_any_instance_of(TabsHelper) - .to receive(:render_tabs) - .with([expected_tab]) - .and_return [expected_tab] - allow(OpenProject::Ui::ExtensibleTabs) .to receive(:enabled_tabs) .with(:user, a_hash_including(user:, current_user:)) @@ -62,7 +57,7 @@ end it "returns an evaluated path" do - tabs = render_extensible_tabs(:user, user:) + tabs = tabs_for_key(:user, user:) expect(response).to have_http_status :ok expect(tabs).to eq([expected_tab]) end From 393b794efda71c4d4dc2adb98c96da1949ee3736 Mon Sep 17 00:00:00 2001 From: Henriette Darge Date: Mon, 15 Jul 2024 11:19:34 +0200 Subject: [PATCH 06/11] Use helper instead of repeating code --- app/helpers/tabs_helper.rb | 4 ++-- app/views/common/_tabs.html.erb | 4 +++- app/views/placeholder_users/edit.html.erb | 6 +----- app/views/users/edit.html.erb | 6 +----- 4 files changed, 7 insertions(+), 13 deletions(-) diff --git a/app/helpers/tabs_helper.rb b/app/helpers/tabs_helper.rb index 64370492b4dd..1b0779a622d2 100644 --- a/app/helpers/tabs_helper.rb +++ b/app/helpers/tabs_helper.rb @@ -28,10 +28,10 @@ module TabsHelper # Renders tabs and their content - def render_tabs(tabs, form = nil) + def render_tabs(tabs, form = nil, with_tab_nav: true) if tabs.any? selected = selected_tab(tabs) - render partial: "common/tabs", locals: { f: form, tabs:, selected_tab: selected } + render partial: "common/tabs", locals: { f: form, tabs:, selected_tab: selected, with_tab_nav: } else content_tag "p", I18n.t(:label_no_data), class: "nodata" end diff --git a/app/views/common/_tabs.html.erb b/app/views/common/_tabs.html.erb index 91e7cee467cc..79e723bc9537 100644 --- a/app/views/common/_tabs.html.erb +++ b/app/views/common/_tabs.html.erb @@ -28,7 +28,9 @@ See COPYRIGHT and LICENSE files for more details. ++#%> <% gon.contentTabs = { tabs: tabs.to_json.html_safe, selected: selected_tab.to_json.html_safe } %> - +<% if with_tab_nav %> + +<% end %> <%= content_tag 'div', render(partial: selected_tab[:partial], locals: { f: f, tab: selected_tab } ), diff --git a/app/views/placeholder_users/edit.html.erb b/app/views/placeholder_users/edit.html.erb index 6ddccd074d67..4696ae23c31a 100644 --- a/app/views/placeholder_users/edit.html.erb +++ b/app/views/placeholder_users/edit.html.erb @@ -31,11 +31,7 @@ See COPYRIGHT and LICENSE files for more details. <% html_title(t(:label_administration), "#{t(:label_edit)} #{PlaceholderUser.model_name.human} #{h(@placeholder_user.name)}") -%> <% tabs = tabs_for_key(:placeholder_user, placeholder_user: @placeholder_user) %> -<% selected_tab = selected_tab(tabs) %> <%= render partial: 'toolbar', locals: { tabs: tabs } %> -<%= content_tag 'div', - render(partial: selected_tab[:partial], locals: { tab: selected_tab } ), - id: "tab-content-#{selected_tab[:name]}", - class: 'tab-content' %> +<%= render_tabs tabs, with_tab_nav: false %> diff --git a/app/views/users/edit.html.erb b/app/views/users/edit.html.erb index 209c7fd054bf..ee1228ec3000 100644 --- a/app/views/users/edit.html.erb +++ b/app/views/users/edit.html.erb @@ -31,11 +31,7 @@ See COPYRIGHT and LICENSE files for more details. <% html_title(t(:label_administration), "#{t(:label_edit)} #{User.model_name.human} #{h(@user.name)}") -%> <% tabs = tabs_for_key(:user, user: @user) %> -<% selected_tab = selected_tab(tabs) %> <%= render partial: 'toolbar', locals: { tabs: tabs } %> -<%= content_tag 'div', - render(partial: selected_tab[:partial], locals: { tab: selected_tab } ), - id: "tab-content-#{selected_tab[:name]}", - class: 'tab-content' %> +<%= render_tabs tabs, with_tab_nav: false %> From 5af5c71a7186333dc8074b860874415f1391a36e Mon Sep 17 00:00:00 2001 From: Henriette Darge Date: Mon, 15 Jul 2024 11:19:52 +0200 Subject: [PATCH 07/11] Introduce PageHeader component in Administration -> User settings -> Groups --- app/controllers/groups_controller.rb | 10 +--- app/views/groups/edit.html.erb | 72 +++++++++++++++++++--------- app/views/groups/index.html.erb | 34 ++++++++----- app/views/groups/new.html.erb | 14 +++++- app/views/groups/show.html.erb | 61 +++++++++++++++-------- 5 files changed, 127 insertions(+), 64 deletions(-) diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb index 85384f3b0cab..7f929d28bb33 100644 --- a/app/controllers/groups_controller.rb +++ b/app/controllers/groups_controller.rb @@ -160,16 +160,8 @@ def visible_group_members? Group.in_project(Project.allowed_to(current_user, :view_members)).exists? end - def default_breadcrumb - if action_name == "index" || !current_user.admin? - t("label_group_plural") - else - ActionController::Base.helpers.link_to(t("label_group_plural"), groups_path) - end - end - def show_local_breadcrumb - true + false end def respond_membership_altered(service_call) diff --git a/app/views/groups/edit.html.erb b/app/views/groups/edit.html.erb index 2b3c27cd14c2..6277a00b3e40 100644 --- a/app/views/groups/edit.html.erb +++ b/app/views/groups/edit.html.erb @@ -29,25 +29,53 @@ See COPYRIGHT and LICENSE files for more details. <% html_title t(:label_administration), "#{t(:label_edit)} #{Group.model_name.human} #{h @group.name}" %> -<% local_assigns[:additional_breadcrumb] = @group.name %> - -<%= breadcrumb_toolbar @group.name do %> -
  • - <%= link_to show_group_path(@group), class: 'button' do %> - <%= op_icon('button--icon icon-user') %> - <%= t(:label_profile) %> - <% end %> -
  • - <% if current_user.admin? %> -
  • - <%= link_to group_path(@group), - data: { confirm: t(:text_are_you_sure) }, - class: 'button -danger', - method: :delete do %> - <%= op_icon('button--icon icon-delete') %> - <%= t(:button_delete) %> - <% end %> -
  • - <% end %> -<% end %> -<%= render_tabs group_settings_tabs(@group) %> +<% 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_tabs tabs, with_tab_nav: false %> diff --git a/app/views/groups/index.html.erb b/app/views/groups/index.html.erb index e0894b0a9918..bf0fe1ceae6b 100644 --- a/app/views/groups/index.html.erb +++ b/app/views/groups/index.html.erb @@ -28,17 +28,29 @@ See COPYRIGHT and LICENSE files for more details. ++#%> <% html_title t(:label_administration), t("label_group_plural") %> -<%= toolbar title: t(:label_group_plural) do %> -
  • - <%= link_to new_group_path, - { class: 'button -primary', - aria: {label: t(:label_group_new)}, - title: t(:label_group_new)} do %> - <%= op_icon('button--icon icon-add') %> - <%= t('activerecord.models.group') %> - <% end %> -
  • -<% end %> + +<%= + render(Primer::OpenProject::PageHeader.new) do |header| + header.with_title { t(:label_group_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_group_plural)]) + end +%> + +<%= + render(Primer::OpenProject::SubHeader.new) do |subheader| + subheader.with_action_button(scheme: :primary, + aria: { label: I18n.t(:label_group_new) }, + title: I18n.t(:label_group_new), + tag: :a, + href: new_group_path) do |button| + button.with_leading_visual_icon(icon: :plus) + t('activerecord.models.group') + end + end +%> + <% if @groups.any? %>
    diff --git a/app/views/groups/new.html.erb b/app/views/groups/new.html.erb index ef6c1e256e03..91988f40cca3 100644 --- a/app/views/groups/new.html.erb +++ b/app/views/groups/new.html.erb @@ -28,8 +28,18 @@ See COPYRIGHT and LICENSE files for more details. ++#%> <% html_title t(:label_administration), t("label_group_new") %> -<% local_assigns[:additional_breadcrumb] = t(:label_group_new) %> -<%= breadcrumb_toolbar t(:label_group_new) %> + + +<%= + render(Primer::OpenProject::PageHeader.new) do |header| + header.with_title { t(:label_group_new) } + 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) }, + t(:label_group_new)]) + end +%> + <%= labelled_tabular_form_for(@group) do |f| %> <%= render partial: 'form', locals: { f: f } %> diff --git a/app/views/groups/show.html.erb b/app/views/groups/show.html.erb index 751eb8966517..369ad1d9d3a0 100644 --- a/app/views/groups/show.html.erb +++ b/app/views/groups/show.html.erb @@ -26,26 +26,47 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. See COPYRIGHT and LICENSE files for more details. ++#%> -<%= breadcrumb_toolbar @group.name do %> - <% if current_user.admin? %> -
  • - <%= link_to edit_group_path(@group), - class: 'button' do %> - <%= op_icon('button--icon icon-edit') %> - <%= t(:button_edit) %> - <% end %> -
  • -
  • - <%= link_to @group, - data: { confirm: t(:text_are_you_sure) }, - class: 'button -danger', - method: :delete do %> - <%= op_icon('button--icon icon-delete') %> - <%= t(:button_delete) %> - <% end %> -
  • - <% end %> -<% end %> +<% html_title h(@group.name), t(:label_group_plural) -%> + +<%= + render(Primer::OpenProject::PageHeader.new) do |header| + header.with_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) }, + 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 +%> <% if @group_users.any? %>
      From b8c8977d67b81e86d656e51c1e9485e6c089c346 Mon Sep 17 00:00:00 2001 From: Henriette Darge Date: Mon, 15 Jul 2024 12:12:15 +0200 Subject: [PATCH 08/11] Introduce PageHeader component in plugin settings pages (e.g avatar or cost settings) --- app/controllers/admin/settings_controller.rb | 7 +-- app/views/admin/settings/show_plugin.html.erb | 12 ++-- .../settings/_openproject_avatars.html.erb | 56 ++++++++++++------- .../app/controllers/cost_types_controller.rb | 10 +--- .../costs/app/views/settings/_costs.html.erb | 40 +++++++++---- 5 files changed, 70 insertions(+), 55 deletions(-) diff --git a/app/controllers/admin/settings_controller.rb b/app/controllers/admin/settings_controller.rb index 6581a1910fba..2e6b34c16c34 100644 --- a/app/controllers/admin/settings_controller.rb +++ b/app/controllers/admin/settings_controller.rb @@ -70,7 +70,7 @@ def update_plugin end def show_local_breadcrumb - true + false end def default_breadcrumb @@ -81,11 +81,6 @@ def default_breadcrumb end end - def breadcrumb_items - [{ href: admin_index_path, text: t("label_administration") }] - end - helper_method :breadcrumb_items - protected def find_plugin diff --git a/app/views/admin/settings/show_plugin.html.erb b/app/views/admin/settings/show_plugin.html.erb index a71d7bb630f8..877efddf782a 100644 --- a/app/views/admin/settings/show_plugin.html.erb +++ b/app/views/admin/settings/show_plugin.html.erb @@ -26,10 +26,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. See COPYRIGHT and LICENSE files for more details. ++#%> -<%= toolbar title: @plugin.name %> -
      - <%= styled_form_tag({controller: '/admin/settings', action: 'update_plugin' }) do %> - <%= render partial: @partial, locals: {settings: @settings}%> - <%= styled_submit_tag t(:button_apply), class: '-primary' %> - <% end %> -
      + + +<% html_title t(:label_administration), @plugin.name %> + +<%= render partial: @partial, locals: {settings: @settings}%> diff --git a/modules/avatars/app/views/settings/_openproject_avatars.html.erb b/modules/avatars/app/views/settings/_openproject_avatars.html.erb index 5391edf8f354..9e5198b9688f 100644 --- a/modules/avatars/app/views/settings/_openproject_avatars.html.erb +++ b/modules/avatars/app/views/settings/_openproject_avatars.html.erb @@ -1,25 +1,39 @@ <% manager = ::OpenProject::Avatars::AvatarManager %> -<% html_title t(:label_administration), 'OpenProject Avatars' %> -
      - <%= t 'avatars.label_gravatar' %> +<%= + render(Primer::OpenProject::PageHeader.new) do |header| + header.with_title { I18n.t(:label_avatar_plural) } + header.with_breadcrumbs([{ href: admin_index_path, text: t("label_administration") }, + { href: admin_settings_users_path, text: t(:label_user_and_permission) }, + I18n.t(:label_avatar_plural)]) + end +%> -
      - <%= styled_label_tag 'settings-enable-gravatars', t('avatars.settings.enable_gravatars') %> - <%= hidden_field_tag 'settings[enable_gravatars]', 0 %> -
      - <%= styled_check_box_tag 'settings[enable_gravatars]', 1, manager.gravatar_enabled?, container_class: '-xslim', id: 'settings-enable-gravatars' %> -
      -
      -
      +
      + <%= styled_form_tag({controller: '/admin/settings', action: 'update_plugin' }) do %> +
      + <%= t 'avatars.label_gravatar' %> -
      - <%= t 'avatars.label_local_avatar' %> -
      - <%= styled_label_tag 'settings-enable-local-avatars', t('avatars.settings.enable_local_avatars') %> - <%= hidden_field_tag 'settings[enable_local_avatars]', 0 %> -
      - <%= styled_check_box_tag 'settings[enable_local_avatars]', 1, manager.local_avatars_enabled?, container_class: '-xslim', id: 'settings-enable-local-avatars' %> -
      -
      -
      +
      + <%= styled_label_tag 'settings-enable-gravatars', t('avatars.settings.enable_gravatars') %> + <%= hidden_field_tag 'settings[enable_gravatars]', 0 %> +
      + <%= styled_check_box_tag 'settings[enable_gravatars]', 1, manager.gravatar_enabled?, container_class: '-xslim', id: 'settings-enable-gravatars' %> +
      +
      +
      + +
      + <%= t 'avatars.label_local_avatar' %> +
      + <%= styled_label_tag 'settings-enable-local-avatars', t('avatars.settings.enable_local_avatars') %> + <%= hidden_field_tag 'settings[enable_local_avatars]', 0 %> +
      + <%= styled_check_box_tag 'settings[enable_local_avatars]', 1, manager.local_avatars_enabled?, container_class: '-xslim', id: 'settings-enable-local-avatars' %> +
      +
      +
      + + <%= styled_submit_tag t(:button_apply), class: '-primary' %> + <% end %> +
      diff --git a/modules/costs/app/controllers/cost_types_controller.rb b/modules/costs/app/controllers/cost_types_controller.rb index 2cbf4b4229fc..a7af129a7237 100644 --- a/modules/costs/app/controllers/cost_types_controller.rb +++ b/modules/costs/app/controllers/cost_types_controller.rb @@ -152,15 +152,7 @@ def find_cost_type render_404 end - def default_breadcrumb - if action_name == "index" - CostType.model_name.human(count: 2) - else - ActionController::Base.helpers.link_to(CostType.model_name.human(count: 2), cost_types_path) - end - end - def show_local_breadcrumb - true + false end end diff --git a/modules/costs/app/views/settings/_costs.html.erb b/modules/costs/app/views/settings/_costs.html.erb index 8426af3b3c2b..e4ca8d63e154 100644 --- a/modules/costs/app/views/settings/_costs.html.erb +++ b/modules/costs/app/views/settings/_costs.html.erb @@ -26,17 +26,33 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. See COPYRIGHT and LICENSE files for more details. ++#%> -<% html_title t(:label_administration), t(:project_module_costs) %> -
      - <%= styled_label_tag :label_currency, t(:label_currency) %> -
      - <%= styled_text_field_tag 'settings[costs_currency]', @settings['costs_currency'], container_class: '-xslim' %> -
      -
      -
      - <%= styled_label_tag :label_currency_format, t(:label_currency_format) %> -
      - <%= styled_text_field_tag 'settings[costs_currency_format]', @settings['costs_currency_format'], container_class: '-xslim' %> -
      +<%= + render(Primer::OpenProject::PageHeader.new) do |header| + header.with_title { I18n.t(:project_module_costs) } + header.with_breadcrumbs([{ href: admin_index_path, text: t("label_administration") }, + { href: url_for({ controller: "/admin/settings", action: "show_plugin", id: :costs }), text: t(:project_module_costs) }, + I18n.t(:label_setting_plural)]) + end +%> + +
      + <%= styled_form_tag({controller: '/admin/settings', action: 'update_plugin' }) do %> + +
      + <%= styled_label_tag :label_currency, t(:label_currency) %> +
      + <%= styled_text_field_tag 'settings[costs_currency]', @settings['costs_currency'], container_class: '-xslim' %> +
      +
      + +
      + <%= styled_label_tag :label_currency_format, t(:label_currency_format) %> +
      + <%= styled_text_field_tag 'settings[costs_currency_format]', @settings['costs_currency_format'], container_class: '-xslim' %> +
      +
      + + <%= styled_submit_tag t(:button_apply), class: '-primary' %> + <% end %>
      From 47b846ff72e70843121d046ebada1ac4bb060ccf Mon Sep 17 00:00:00 2001 From: Henriette Darge Date: Mon, 15 Jul 2024 12:12:50 +0200 Subject: [PATCH 09/11] Introduce PageHeader component in Time & Costs -> Cost types to harmonise it with the Time & Costs -> Settings page --- .../costs/app/views/cost_types/edit.html.erb | 15 ++- .../costs/app/views/cost_types/index.html.erb | 91 +++++++++++-------- 2 files changed, 62 insertions(+), 44 deletions(-) diff --git a/modules/costs/app/views/cost_types/edit.html.erb b/modules/costs/app/views/cost_types/edit.html.erb index 9457795b8730..08a9cfc559c4 100644 --- a/modules/costs/app/views/cost_types/edit.html.erb +++ b/modules/costs/app/views/cost_types/edit.html.erb @@ -29,14 +29,21 @@ See COPYRIGHT and LICENSE files for more details. <% if(@cost_type.id) %> <% html_title t(:label_cost_type_specific, id: @cost_type.id, name: @cost_type.name) %> - <% local_assigns[:additional_breadcrumb] = @cost_type.name %> + <% title = @cost_type.name %> <% else %> <% html_title t(:label_administration), t(:label_cost_type_plural) %> - <% local_assigns[:additional_breadcrumb] = t(:label_new) + ' ' + I18n.t('activerecord.models.cost_type.one') %> + <% title = t(:label_new) + ' ' + I18n.t('activerecord.models.cost_type.one') %> <% end %> - -<%= toolbar title: CostType.model_name.human %> +<%= + render(Primer::OpenProject::PageHeader.new) do |header| + header.with_title { title } + header.with_breadcrumbs([{ href: admin_index_path, text: t("label_administration") }, + { href: url_for({ controller: "/admin/settings", action: "show_plugin", id: :costs }), text: t(:project_module_costs) }, + { href: cost_types_path, text: t(:label_cost_type_plural) }, + title]) + end +%> <%= labelled_tabular_form_for @cost_type do |f| %> diff --git a/modules/costs/app/views/cost_types/index.html.erb b/modules/costs/app/views/cost_types/index.html.erb index e63392fb7f8d..1169c6bb3754 100644 --- a/modules/costs/app/views/cost_types/index.html.erb +++ b/modules/costs/app/views/cost_types/index.html.erb @@ -28,48 +28,59 @@ See COPYRIGHT and LICENSE files for more details. ++#%> <% html_title t(:label_administration), t(:label_cost_type_plural) %> -<%= toolbar title: CostType.model_name.human(count: 2) do %> -
    • - - <%= op_icon('button--icon icon-add') %> - <%= CostType.model_name.human %> - -
    • -<% end %> -<%= styled_form_tag(cost_types_path, { method: :get, id: 'query_form' }) do %> -
      - <%= t(:label_filter_plural) %> -
        -
      • - <%= styled_label_tag :fixed_date, t(:'attributes.fixed_date'), class: 'simple-filters--filter-name' %> -
        - <%= angular_component_tag 'op-basic-single-date-picker', - inputs: { - value: @fixed_date, - id: :start_date, - name: :fixed_date - } - %> -
        -
      • -
      • - <%= styled_label_tag :include_deleted, t(:caption_show_locked), class: 'simple-filters--filter-name -small' %> -
        - <%= styled_check_box_tag :include_deleted, "1", @include_deleted, autocomplete: "off" %> -
        -
      • -
      • - <%= submit_tag t(:button_apply), class: 'button -primary -small' %> - <%= link_to t(:button_clear), cost_types_path, class: 'button -small -with-icon icon-undo' %> -
      • -
      -
      -<% end %> +<%= + render(Primer::OpenProject::PageHeader.new) do |header| + header.with_title { I18n.t(:label_cost_type_plural) } + header.with_breadcrumbs([{ href: admin_index_path, text: t("label_administration") }, + { href: url_for({ controller: "/admin/settings", action: "show_plugin", id: :costs }), text: t(:project_module_costs) }, + I18n.t(:label_cost_type_plural)]) + end +%> + +<%= render(Primer::OpenProject::SubHeader.new) do |subheader| %> + <% subheader.with_action_button(scheme: :primary, + aria: { label: I18n.t(:button_add_cost_type) }, + title: I18n.t(:button_add_cost_type), + tag: :a, + href: new_cost_type_path) do |button| + button.with_leading_visual_icon(icon: :plus) + CostType.model_name.human + end %> + + <% subheader.with_bottom_pane_component do %> + <%= styled_form_tag(cost_types_path, { method: :get, id: 'query_form' }) do %> +
      + <%= t(:label_filter_plural) %> +
        +
      • + <%= styled_label_tag :fixed_date, t(:'attributes.fixed_date'), class: 'simple-filters--filter-name' %> +
        + <%= angular_component_tag 'op-basic-single-date-picker', + inputs: { + value: @fixed_date, + id: :start_date, + name: :fixed_date + } + %> +
        +
      • +
      • + <%= styled_label_tag :include_deleted, t(:caption_show_locked), class: 'simple-filters--filter-name -small' %> +
        + <%= styled_check_box_tag :include_deleted, "1", @include_deleted, autocomplete: "off" %> +
        +
      • +
      • + <%= submit_tag t(:button_apply), class: 'button -primary -small' %> + <%= link_to t(:button_clear), cost_types_path, class: 'button -small -with-icon icon-undo' %> +
      • +
      +
      + <% end %> + <% end %> + <% end %> - <%= render partial: 'list' %> <% if @include_deleted %> From c25336470235c6324655cde52d2723842ff4a42a Mon Sep 17 00:00:00 2001 From: Henriette Darge Date: Mon, 15 Jul 2024 13:11:12 +0200 Subject: [PATCH 10/11] Fix user_helper --- app/helpers/users_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb index 9e1eeaf10c28..c5f4f6c9f91d 100644 --- a/app/helpers/users_helper.rb +++ b/app/helpers/users_helper.rb @@ -113,7 +113,7 @@ def change_user_status_icons def change_user_status_buttons(user) build_change_user_status_action(user) do |title, name| - Primer::Beta::Button.new(name:, type: :submit, title:) do |button| + render Primer::Beta::Button.new(name:, type: :submit, title:) do |button| button.with_leading_visual_icon(icon: change_user_status_icons[name]) title end From 46860150b11588057516ad4344ee387e490a8622 Mon Sep 17 00:00:00 2001 From: Henriette Darge Date: Mon, 15 Jul 2024 14:28:09 +0200 Subject: [PATCH 11/11] Adapt tests to new PageHeader structure --- app/helpers/users_helper.rb | 2 +- app/views/groups/show.html.erb | 3 ++- app/views/placeholder_users/_toolbar.html.erb | 1 + app/views/placeholder_users/show.html.erb | 1 + app/views/roles/index.html.erb | 1 + spec/features/groups/group_show_spec.rb | 8 ++++---- spec/features/placeholder_users/delete_spec.rb | 8 ++++---- spec/features/roles/create_spec.rb | 4 ++-- spec/features/users/edit_users_spec.rb | 12 ++++++------ .../pages/admin/individual_principals/edit.rb | 2 +- spec/support/pages/admin/users/edit.rb | 4 ++-- spec/support/pages/groups.rb | 4 ++-- 12 files changed, 27 insertions(+), 23 deletions(-) diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb index c5f4f6c9f91d..efe0e2795a48 100644 --- a/app/helpers/users_helper.rb +++ b/app/helpers/users_helper.rb @@ -128,7 +128,7 @@ def change_user_status_links(user) href: change_status_user_path(user, name.to_sym => "1", back_url: request.fullpath), - method: :post) do |button| + data: { method: :post }) do |button| button.with_leading_visual_icon(icon: change_user_status_icons[name]) title end diff --git a/app/views/groups/show.html.erb b/app/views/groups/show.html.erb index 369ad1d9d3a0..2891a345637c 100644 --- a/app/views/groups/show.html.erb +++ b/app/views/groups/show.html.erb @@ -30,7 +30,7 @@ See COPYRIGHT and LICENSE files for more details. <%= render(Primer::OpenProject::PageHeader.new) do |header| - header.with_title { @group.name } + header.with_title(test_selector: "groups--title") { @group.name } header.with_breadcrumbs( [ { href: groups_path, text: t(:label_group_plural) }, @@ -44,6 +44,7 @@ See COPYRIGHT and LICENSE files for more details. 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) diff --git a/app/views/placeholder_users/_toolbar.html.erb b/app/views/placeholder_users/_toolbar.html.erb index d969dec61a26..2d5f18d91532 100644 --- a/app/views/placeholder_users/_toolbar.html.erb +++ b/app/views/placeholder_users/_toolbar.html.erb @@ -57,6 +57,7 @@ See COPYRIGHT and LICENSE files for more details. 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| diff --git a/app/views/placeholder_users/show.html.erb b/app/views/placeholder_users/show.html.erb index 5fc19af8b283..72537fe3ef04 100644 --- a/app/views/placeholder_users/show.html.erb +++ b/app/views/placeholder_users/show.html.erb @@ -64,6 +64,7 @@ See COPYRIGHT and LICENSE files for more details. 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| diff --git a/app/views/roles/index.html.erb b/app/views/roles/index.html.erb index 2e03178fbcfa..2c87cc4218a5 100644 --- a/app/views/roles/index.html.erb +++ b/app/views/roles/index.html.erb @@ -43,6 +43,7 @@ See COPYRIGHT and LICENSE files for more details. aria: { label: I18n.t(:label_role_new) }, title: I18n.t(:label_role_new), tag: :a, + test_selector: "roles--create-button", href: new_role_path) do |button| button.with_leading_visual_icon(icon: :plus) Role.model_name.human diff --git a/spec/features/groups/group_show_spec.rb b/spec/features/groups/group_show_spec.rb index e1971fb18d18..87ff37e61d43 100644 --- a/spec/features/groups/group_show_spec.rb +++ b/spec/features/groups/group_show_spec.rb @@ -42,8 +42,8 @@ it "I can visit the group page" do visit show_group_path(group) - expect(page).to have_css("h2", text: "Bob's Team") - expect(page).to have_css(".toolbar-item", text: "Edit") + expect(page).to have_test_selector("groups--title", text: "Bob's Team") + expect(page).to have_test_selector("groups--edit-group-button", text: "Edit") expect(page).to have_css("li", text: member.name) end end @@ -53,8 +53,8 @@ it "I can visit the group page" do visit show_group_path(group) - expect(page).to have_css("h2", text: "Bob's Team") - expect(page).to have_no_css(".toolbar-item") + expect(page).to have_test_selector("groups--title", text: "Bob's Team") + expect(page).not_to have_test_selector("groups--edit-group-button") expect(page).to have_no_css("li", text: member.name) end end diff --git a/spec/features/placeholder_users/delete_spec.rb b/spec/features/placeholder_users/delete_spec.rb index 87763aaee282..9e67de49bec2 100644 --- a/spec/features/placeholder_users/delete_spec.rb +++ b/spec/features/placeholder_users/delete_spec.rb @@ -35,11 +35,11 @@ it "can delete name" do visit placeholder_user_path(placeholder_user) - expect(page).to have_css ".button", text: "Delete" + expect(page).to have_test_selector "placeholder-user--delete-button", text: "Delete" visit edit_placeholder_user_path(placeholder_user) - expect(page).to have_css ".button", text: "Delete" + expect(page).to have_test_selector "placeholder-user--delete-button", text: "Delete" click_on "Delete" # Expect to be on delete confirmation @@ -89,11 +89,11 @@ visit placeholder_user_path(placeholder_user) - expect(page).to have_css ".button.-disabled", text: "Delete" + expect(page).to have_css("[data-test-selector='placeholder-user--delete-button'][disabled='disabled']", text: "Delete") visit edit_placeholder_user_path(placeholder_user) - expect(page).to have_css ".button.-disabled", text: "Delete" + expect(page).to have_css("[data-test-selector='placeholder-user--delete-button'][disabled='disabled']", text: "Delete") end end diff --git a/spec/features/roles/create_spec.rb b/spec/features/roles/create_spec.rb index 5b75ce125991..a1c4500254a4 100644 --- a/spec/features/roles/create_spec.rb +++ b/spec/features/roles/create_spec.rb @@ -44,8 +44,8 @@ it "allows creating roles and handles errors" do visit roles_path - within ".toolbar-item" do - click_link "Role" + within ".SubHeader" do + page.find_test_selector("roles--create-button").click end fill_in "Name", with: existing_role.name diff --git a/spec/features/users/edit_users_spec.rb b/spec/features/users/edit_users_spec.rb index 07e481b93942..18d0c003c3ac 100644 --- a/spec/features/users/edit_users_spec.rb +++ b/spec/features/users/edit_users_spec.rb @@ -85,7 +85,7 @@ def user_password end def have_visible_tab(label) - have_css(".op-tab-row--link", text: label.upcase) + have_css(".tabnav-tab", text: label) end context "as admin" do @@ -93,7 +93,7 @@ def have_visible_tab(label) another_admin = create(:admin) visit edit_user_path(another_admin) - expect(page).to have_visible_tab("GENERAL") + expect(page).to have_visible_tab("General") end end @@ -104,7 +104,7 @@ def have_visible_tab(label) it "can too edit the user" do visit edit_user_path(user) - expect(page).to have_visible_tab("GENERAL") + expect(page).to have_visible_tab("General") expect(page).to have_no_css(".admin-overview-menu-item", text: "Overview") expect(page).to have_no_css(".users-and-permissions-menu-item", text: "Users and permissions") @@ -138,7 +138,7 @@ def have_visible_tab(label) it "can reinvite the user" do visit edit_user_path(user) - click_button "Send invitation" + click_on "Send invitation" expect(page).to have_css(".op-toast.-success", text: "An invitation has been sent to foo@example.com") end @@ -146,8 +146,8 @@ def have_visible_tab(label) it "can not edit attributes of an admin user" do visit edit_user_path(admin) - expect(page).to have_visible_tab("PROJECTS") - expect(page).not_to have_visible_tab("GENERAL") + expect(page).to have_visible_tab("Projects") + expect(page).not_to have_visible_tab("General") end end end diff --git a/spec/support/pages/admin/individual_principals/edit.rb b/spec/support/pages/admin/individual_principals/edit.rb index a8ca6fc2420d..5900da868adc 100644 --- a/spec/support/pages/admin/individual_principals/edit.rb +++ b/spec/support/pages/admin/individual_principals/edit.rb @@ -47,7 +47,7 @@ def path end def open_projects_tab! - within(".content--tabs") do + within(".PageHeader-tabNav") do click_on "Projects" end end diff --git a/spec/support/pages/admin/users/edit.rb b/spec/support/pages/admin/users/edit.rb index 23abae8920f3..028022ac6c10 100644 --- a/spec/support/pages/admin/users/edit.rb +++ b/spec/support/pages/admin/users/edit.rb @@ -105,8 +105,8 @@ def select_project!(project_name) end def activate! - within ".toolbar-items" do - click_button "Activate" + within ".PageHeader-actions" do + click_on "Activate" end end end diff --git a/spec/support/pages/groups.rb b/spec/support/pages/groups.rb index 40bfbd13272c..7eb7f2709a0c 100644 --- a/spec/support/pages/groups.rb +++ b/spec/support/pages/groups.rb @@ -82,13 +82,13 @@ def path end def open_users_tab! - within(".content--tabs") do + within(".PageHeader-tabNav") do click_on "Users" end end def open_projects_tab! - within(".content--tabs") do + within(".PageHeader-tabNav") do click_on "Projects" end end