From d7c006ce822a044d52e058da65597ed2acff7798 Mon Sep 17 00:00:00 2001 From: Henriette Darge Date: Mon, 19 May 2025 12:29:45 +0200 Subject: [PATCH] Update SubHeader implementations to new mobile requirements in version 0.66.1 --- Gemfile | 2 +- Gemfile.lock | 6 +- app/components/add_button_component.html.erb | 28 +++---- app/components/add_button_component.rb | 16 +++- .../hierarchy/items_component.html.erb | 7 +- .../enumerations/index_component.html.erb | 5 +- .../index_sub_header_component.html.erb | 9 +-- .../index_sub_header_component.html.erb | 40 +++++----- .../index_sub_header_component.html.erb | 6 +- .../new_section_dialog_component.html.erb | 11 +++ .../new_section_dialog_component.rb | 32 ++------ .../header_component.html.erb | 23 +++--- .../index_component.html.erb | 19 ++--- .../users/index_sub_header_component.html.erb | 7 +- .../show_sub_header_component.html.erb | 7 +- ...roject_custom_field_sections_controller.rb | 5 ++ .../custom_field_projects/index.html.erb | 19 ++--- .../project_mappings.html.erb | 19 ++--- app/views/attribute_help_texts/index.html.erb | 7 +- app/views/colors/index.html.erb | 7 +- app/views/custom_actions/index.html.erb | 7 +- app/views/custom_fields/index.html.erb | 7 +- app/views/forums/index.html.erb | 7 +- app/views/forums/show.html.erb | 7 +- app/views/groups/index.html.erb | 7 +- app/views/ldap_auth_sources/index.html.erb | 7 +- app/views/news/index.html.erb | 7 +- app/views/oauth/applications/index.html.erb | 7 +- app/views/placeholder_users/index.html.erb | 7 +- .../projects/settings/versions/show.html.erb | 7 +- .../work_packages/categories/show.html.erb | 7 +- .../work_packages/custom_fields/show.html.erb | 7 +- app/views/roles/index.html.erb | 7 +- app/views/statuses/index.html.erb | 7 +- app/views/types/index.html.erb | 7 +- app/views/versions/index.html.erb | 7 +- config/routes.rb | 3 + frontend/package-lock.json | 28 +++---- frontend/package.json | 4 +- .../open_project/common/sub_header_preview.rb | 14 +++- .../app/views/saml/providers/index.html.erb | 7 +- .../views/rb_master_backlogs/index.html.erb | 7 +- .../bim/ifc_models/ifc_models/index.html.erb | 7 +- .../app/views/boards/boards/index.html.erb | 4 +- .../budgets/app/views/budgets/index.html.erb | 7 +- .../views/calendar/calendars/index.html.erb | 4 +- .../sub_header_component.html.erb | 20 ++--- .../app/views/admin/cost_types/index.html.erb | 7 +- .../app/views/documents/index.html.erb | 7 +- .../app/views/deploy_targets/index.html.erb | 7 +- .../synchronized_groups/index.html.erb | 40 ++++------ .../combined_filter_component.html.erb | 28 ------- .../index_sub_header_component.html.erb | 77 +++++++++++-------- .../meetings/index_sub_header_component.rb | 17 +++- .../show_page_sub_header_component.html.erb | 44 +++++------ .../openid_connect/providers/index.html.erb | 32 +++----- .../admin/health_status/show.html.erb | 9 ++- .../storages/admin/storages/index.html.erb | 39 +++++----- .../storages/project_storages/index.html.erb | 19 ++--- .../team_planner/team_planner/index.html.erb | 4 +- .../team_planner/overview.html.erb | 4 +- .../my/two_factor_devices/index.html.erb | 35 ++++----- .../webhooks/outgoing/admin/index.html.erb | 7 +- 63 files changed, 398 insertions(+), 470 deletions(-) create mode 100644 app/components/settings/project_custom_field_sections/new_section_dialog_component.html.erb rename modules/meeting/app/components/meetings/combined_filter_component.rb => app/components/settings/project_custom_field_sections/new_section_dialog_component.rb (62%) delete mode 100644 modules/meeting/app/components/meetings/combined_filter_component.html.erb diff --git a/Gemfile b/Gemfile index b471946ac17..4f1b8addec5 100644 --- a/Gemfile +++ b/Gemfile @@ -418,4 +418,4 @@ end gem "openproject-octicons", "~>19.25.0" gem "openproject-octicons_helper", "~>19.25.0" -gem "openproject-primer_view_components", "~>0.65.0" +gem "openproject-primer_view_components", "~>0.66.1" diff --git a/Gemfile.lock b/Gemfile.lock index 34d59737413..747306d22bf 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -860,7 +860,7 @@ GEM actionview openproject-octicons (= 19.25.0) railties - openproject-primer_view_components (0.65.0) + openproject-primer_view_components (0.66.1) actionview (>= 7.1.0) activesupport (>= 7.1.0) openproject-octicons (>= 19.25.0) @@ -1447,7 +1447,7 @@ DEPENDENCIES openproject-octicons (~> 19.25.0) openproject-octicons_helper (~> 19.25.0) openproject-openid_connect! - openproject-primer_view_components (~> 0.65.0) + openproject-primer_view_components (~> 0.66.1) openproject-recaptcha! openproject-reporting! openproject-storages! @@ -1818,7 +1818,7 @@ CHECKSUMS openproject-octicons (19.25.0) sha256=16fc221375e693f0e893b1c208286f2d7719ae4dfe080c5415642b221f51f550 openproject-octicons_helper (19.25.0) sha256=9b1778a67b0015ebe84ca0471f74e31004b985a8dcaaa443f7a2ac365b0a4e2d openproject-openid_connect (1.0.0) - openproject-primer_view_components (0.65.0) sha256=d8d4ebeb90648e158e270845e9c336497f225bd8b608f08512264682b4fcd9ee + openproject-primer_view_components (0.66.1) sha256=dec183877f43435118f8bf1127fdfd4661ab0d1cf3b84bb70a96b6f3940aded9 openproject-recaptcha (1.0.0) openproject-reporting (1.0.0) openproject-storages (1.0.0) diff --git a/app/components/add_button_component.html.erb b/app/components/add_button_component.html.erb index b4903d3eb93..730e0835a37 100644 --- a/app/components/add_button_component.html.erb +++ b/app/components/add_button_component.html.erb @@ -1,14 +1,14 @@ -<%= render( - Primer::Beta::Button.new( - scheme: :primary, - aria: { label: aria_label }, - title:, - test_selector:, - tag: :a, - id:, - href: dynamic_path - ) - ) do |button| - button.with_leading_visual_icon(icon: :plus) - label_text - end %> +<%= + subheader.with_action_button( + scheme: :primary, + leading_icon: leading_icon, + label: aria_label, + title:, + tag: :a, + id:, + href: dynamic_path, + test_selector: + ) do + label_text + end +%> diff --git a/app/components/add_button_component.rb b/app/components/add_button_component.rb index 973e2283ece..1cac0423a61 100644 --- a/app/components/add_button_component.rb +++ b/app/components/add_button_component.rb @@ -30,7 +30,13 @@ # class AddButtonComponent < ApplicationComponent - options :current_project + attr_reader :subheader, :current_project + + def initialize(subheader:, current_project: nil) + super + @subheader = subheader + @current_project = current_project + end def render? raise "Implement the conditions for which the component should render or not" @@ -44,6 +50,14 @@ class AddButtonComponent < ApplicationComponent raise "Implement the id for this component" end + def test_selector + raise "Implement the test_selector for this component" + end + + def leading_icon + :plus + end + def title accessibility_label_text end diff --git a/app/components/admin/custom_fields/hierarchy/items_component.html.erb b/app/components/admin/custom_fields/hierarchy/items_component.html.erb index 84b71f90a75..0c44302dd74 100644 --- a/app/components/admin/custom_fields/hierarchy/items_component.html.erb +++ b/app/components/admin/custom_fields/hierarchy/items_component.html.erb @@ -34,8 +34,11 @@ See COPYRIGHT and LICENSE files for more details. flex_layout do |container| container.with_row do render(Primer::OpenProject::SubHeader.new) do |subheader| - subheader.with_action_button(tag: :a, scheme: :primary, href: new_item_path) do |button| - button.with_leading_visual_icon(icon: :plus) + subheader.with_action_button(tag: :a, + scheme: :primary, + leading_icon: :plus, + label: t(:label_item), + href: new_item_path) do I18n.t(:label_item) end end diff --git a/app/components/admin/enumerations/index_component.html.erb b/app/components/admin/enumerations/index_component.html.erb index 9145f180e87..32d7c171bdb 100644 --- a/app/components/admin/enumerations/index_component.html.erb +++ b/app/components/admin/enumerations/index_component.html.erb @@ -5,11 +5,12 @@ component_wrapper do render(Primer::OpenProject::SubHeader.new) do |subheader| subheader.with_action_button( scheme: :primary, + leading_icon: :plus, + label: t(:button_add), tag: :a, href: helpers.url_for(action: :new), test_selector: "add-enumeration-button" - ) do |button| - button.with_leading_visual_icon(icon: :plus) + ) do I18n.t(:button_add) end end diff --git a/app/components/members/index_sub_header_component.html.erb b/app/components/members/index_sub_header_component.html.erb index c2e2105777b..6b7975caf00 100644 --- a/app/components/members/index_sub_header_component.html.erb +++ b/app/components/members/index_sub_header_component.html.erb @@ -1,8 +1,6 @@ <%= render(Primer::OpenProject::SubHeader.new) do |subheader| subheader.with_filter_button( - label: I18n.t(:description_filter), id: "filter-member-button", - aria: { label: I18n.t(:description_filter) }, class: "toggle-member-filter-link", data: filter_button_data_attributes ) do @@ -11,12 +9,11 @@ subheader.with_action_button( scheme: :primary, - aria: { label: I18n.t(:button_add_member) }, - title: I18n.t(:button_add_member), + leading_icon: :plus, + label: t(:button_add_member), id: "add-member-button", data: add_button_data_attributes - ) do |button| - button.with_leading_visual_icon(icon: :plus) + ) do t("activerecord.models.member") end diff --git a/app/components/notifications/index_sub_header_component.html.erb b/app/components/notifications/index_sub_header_component.html.erb index 90cc56f2287..293f4dc22e2 100644 --- a/app/components/notifications/index_sub_header_component.html.erb +++ b/app/components/notifications/index_sub_header_component.html.erb @@ -1,21 +1,21 @@ <%= render(Primer::OpenProject::SubHeader.new) do |subheader| - subheader.with_filter_component do - render(Primer::Alpha::SegmentedControl.new("aria-label": I18n.t(:label_filter_plural))) do |control| - control.with_item( - tag: :a, - href: notifications_path(facet: nil, **current_filters), - label: t("notifications.facets.unread"), - title: t("notifications.facets.unread_title"), - selected: @facet != "all" - ) - control.with_item( - tag: :a, - href: notifications_path(facet: "all", **current_filters), - label: t("notifications.facets.all"), - title: t("notifications.facets.all_title"), - selected: @facet == "all" - ) - end + subheader.with_segmented_control("aria-label": I18n.t(:label_filter_plural)) do |control| + control.with_item( + tag: :a, + icon: :unread, + href: notifications_path(facet: nil, **current_filters), + label: t("notifications.facets.unread"), + title: t("notifications.facets.unread_title"), + selected: @facet != "all" + ) + control.with_item( + tag: :a, + icon: :read, + href: notifications_path(facet: "all", **current_filters), + label: t("notifications.facets.all"), + title: t("notifications.facets.all_title"), + selected: @facet == "all" + ) end subheader.with_action_button( @@ -23,11 +23,11 @@ href: mark_all_read_notifications_path(**current_filters), data: { method: :post, confirm: I18n.t("js.notifications.center.mark_all_read_confirmation") }, size: :medium, - aria: { label: I18n.t("js.notifications.center.mark_all_read") }, + leading_icon: :"op-read-all", + label: I18n.t("js.notifications.center.mark_all_read"), disabled: !unread_notifications?, test_selector: "mark-all-as-read-button" - ) do |button| - button.with_leading_visual_icon(icon: :"op-read-all") + ) do I18n.t("js.notifications.center.mark_all_read") end end %> diff --git a/app/components/projects/index_sub_header_component.html.erb b/app/components/projects/index_sub_header_component.html.erb index 5e9557710bc..e01a070bc30 100644 --- a/app/components/projects/index_sub_header_component.html.erb +++ b/app/components/projects/index_sub_header_component.html.erb @@ -22,12 +22,12 @@ tag: :a, href: new_project_path, scheme: :primary, + leading_icon: :plus, + label: I18n.t(:label_project_new), disabled: @disable_buttons, size: :medium, - aria: { label: I18n.t(:label_project_new) }, data: { "test-selector": "project-new-button" } - ) do |button| - button.with_leading_visual_icon(icon: :plus) + ) do Project.model_name.human end end diff --git a/app/components/settings/project_custom_field_sections/new_section_dialog_component.html.erb b/app/components/settings/project_custom_field_sections/new_section_dialog_component.html.erb new file mode 100644 index 00000000000..aef337563e2 --- /dev/null +++ b/app/components/settings/project_custom_field_sections/new_section_dialog_component.html.erb @@ -0,0 +1,11 @@ +<%= render( + Primer::Alpha::Dialog.new( + title: t("settings.project_attributes.label_new_section"), + size: :medium_portrait, + id: MODAL_ID + ) + ) do |d| %> + <% d.with_body do %> + <%= render(Settings::ProjectCustomFieldSections::DialogBodyFormComponent.new) %> + <% end %> +<% end %> diff --git a/modules/meeting/app/components/meetings/combined_filter_component.rb b/app/components/settings/project_custom_field_sections/new_section_dialog_component.rb similarity index 62% rename from modules/meeting/app/components/meetings/combined_filter_component.rb rename to app/components/settings/project_custom_field_sections/new_section_dialog_component.rb index 369c28497f2..337c094a86e 100644 --- a/modules/meeting/app/components/meetings/combined_filter_component.rb +++ b/app/components/settings/project_custom_field_sections/new_section_dialog_component.rb @@ -1,4 +1,3 @@ -# frozen_string_literal: true #-- copyright # OpenProject is an open source project management software. # Copyright (C) the OpenProject GmbH @@ -27,32 +26,13 @@ # See COPYRIGHT and LICENSE files for more details. #++ -module Meetings - class CombinedFilterComponent < ApplicationComponent - include ApplicationHelper - include OpTurbo::Streamable - include OpPrimer::ComponentHelpers - include Redmine::I18n +module Settings + module ProjectCustomFieldSections + class NewSectionDialogComponent < ApplicationComponent + include OpTurbo::Streamable - def initialize(query:, params:, project: nil) - super() - - @query = query - @project = project - @params = params - end - - def dynamic_path(upcoming: true) - polymorphic_path([@project, :meetings], current_params.merge(upcoming:)) - end - - def upcoming_query? - filter = @query.filters.find { |f| f.name == :time } - filter ? !filter.past? : true - end - - def current_params - @current_params ||= params.slice(:filters, :page, :per_page).permit! + MODAL_ID = "project-custom-field-section-dialog" + FORM_ID = "project-custom-field-section-dialog-form" end end end diff --git a/app/components/settings/project_custom_fields/header_component.html.erb b/app/components/settings/project_custom_fields/header_component.html.erb index cf7fe4fbae8..fa0ad4da0e4 100644 --- a/app/components/settings/project_custom_fields/header_component.html.erb +++ b/app/components/settings/project_custom_fields/header_component.html.erb @@ -9,27 +9,22 @@ <%= render Primer::OpenProject::SubHeader.new do |subheader| - subheader.with_action_component do - render(Primer::Alpha::Dialog.new(id: "project-custom-field-section-dialog", title: t("settings.project_attributes.label_new_section"), size: :medium_portrait)) do |dialog| - dialog.with_show_button("aria-label": t("settings.project_attributes.label_new_section")) do |button| - button.with_leading_visual_icon(icon: :plus) - t("settings.project_attributes.label_new_section") - end - dialog.with_body do - render(Settings::ProjectCustomFieldSections::DialogBodyFormComponent.new) - end - end + subheader.with_action_button(leading_icon: :plus, + label: t("settings.project_attributes.label_new_section"), + tag: :a, + href: new_link_admin_settings_project_custom_field_sections_path, + data: { controller: "async-dialog" }) do + t("settings.project_attributes.label_new_section") end subheader.with_action_button( tag: :a, href: new_admin_settings_project_custom_field_path(type: "ProjectCustomField"), scheme: :primary, + leading_icon: :plus, + label: t("settings.project_attributes.label_new_attribute"), data: { turbo: "false", test_selector: "new-project-custom-field-button" }, - mobile_icon: :plus, - mobile_label: t("settings.project_attributes.label_new_attribute") - ) do |button| - button.with_leading_visual_icon(icon: :plus) + ) do t("settings.project_attributes.label_new_attribute") end end diff --git a/app/components/settings/project_life_cycle_step_definitions/index_component.html.erb b/app/components/settings/project_life_cycle_step_definitions/index_component.html.erb index cec37c6b1df..e6a8145822c 100644 --- a/app/components/settings/project_life_cycle_step_definitions/index_component.html.erb +++ b/app/components/settings/project_life_cycle_step_definitions/index_component.html.erb @@ -48,18 +48,13 @@ See COPYRIGHT and LICENSE files for more details. "projects--settings--border-box-filter-target": "filter" } ) - subheader.with_action_component do - render( - Primer::Beta::Button.new( - scheme: :primary, - aria: { label: I18n.t("settings.project_phase_definitions.label_add_description") }, - tag: :a, - href: new_admin_settings_project_phase_definition_path - ) - ) do |button| - button.with_leading_visual_icon(icon: :plus) - I18n.t("settings.project_phase_definitions.label_add") - end + + subheader.with_action_button(scheme: :primary, + leading_icon: :plus, + label: I18n.t("settings.project_phase_definitions.label_add_description"), + tag: :a, + href: new_admin_settings_project_phase_definition_path) do + I18n.t("settings.project_phase_definitions.label_add") end end else diff --git a/app/components/users/index_sub_header_component.html.erb b/app/components/users/index_sub_header_component.html.erb index 3a7548f9880..acad7b63cc4 100644 --- a/app/components/users/index_sub_header_component.html.erb +++ b/app/components/users/index_sub_header_component.html.erb @@ -2,12 +2,11 @@ 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), + leading_icon: :plus, + label: t(:label_user_new), tag: :a, href: new_user_path - ) do |button| - button.with_leading_visual_icon(icon: :plus) + ) do t("activerecord.models.user") end diff --git a/app/components/wiki_pages/show_sub_header_component.html.erb b/app/components/wiki_pages/show_sub_header_component.html.erb index 3f8b22240d9..5f92db43f0d 100644 --- a/app/components/wiki_pages/show_sub_header_component.html.erb +++ b/app/components/wiki_pages/show_sub_header_component.html.erb @@ -31,13 +31,12 @@ See COPYRIGHT and LICENSE files for more details. render(Primer::OpenProject::SubHeader.new) do |subheader| subheader.with_action_button( scheme: :primary, - aria: { label: t("wiki.index.no_results_content_text") }, - title: t("wiki.index.no_results_content_text"), + leading_icon: :plus, + label: t("wiki.index.no_results_content_text"), tag: :a, test_selector: "wiki-new-child-button", href: url_for({ controller: "/wiki", action: "new_child", project_id: @project.identifier, id: @page }) - ) do |button| - button.with_leading_visual_icon(icon: :plus) + ) do t(:create_wiki_page_button) end end diff --git a/app/controllers/admin/settings/project_custom_field_sections_controller.rb b/app/controllers/admin/settings/project_custom_field_sections_controller.rb index 20264164a54..85248086b73 100644 --- a/app/controllers/admin/settings/project_custom_field_sections_controller.rb +++ b/app/controllers/admin/settings/project_custom_field_sections_controller.rb @@ -30,6 +30,7 @@ module Admin::Settings class ProjectCustomFieldSectionsController < ::Admin::SettingsController include OpTurbo::ComponentStream include Admin::Settings::ProjectCustomFields::ComponentStreams + include OpTurbo::DialogStreamHelper before_action :set_project_custom_field_section, only: %i[update move drop destroy] @@ -102,6 +103,10 @@ module Admin::Settings respond_with_turbo_streams end + def new_link + respond_with_dialog Settings::ProjectCustomFieldSections::NewSectionDialogComponent.new + end + private def set_project_custom_field_section diff --git a/app/views/admin/custom_fields/custom_field_projects/index.html.erb b/app/views/admin/custom_fields/custom_field_projects/index.html.erb index f66a2cec7e0..32f9a4f0c84 100644 --- a/app/views/admin/custom_fields/custom_field_projects/index.html.erb +++ b/app/views/admin/custom_fields/custom_field_projects/index.html.erb @@ -41,18 +41,13 @@ See COPYRIGHT and LICENSE files for more details. <%= unless @custom_field.is_for_all? render(Primer::OpenProject::SubHeader.new(test_selector: "add-projects-sub-header")) do |component| - component.with_action_component do - render( - Primer::Beta::Button.new( - scheme: :primary, - tag: :a, - href: new_custom_field_project_path(@custom_field), - data: { controller: "async-dialog" } - ) - ) do |button| - button.with_leading_visual_icon(icon: "op-include-projects") - I18n.t(:label_add_projects) - end + component.with_action_button(scheme: :primary, + leading_icon: :"op-include-projects", + label: I18n.t(:label_add_projects), + tag: :a, + href: new_custom_field_project_path(@custom_field), + data: { controller: "async-dialog" }) do + I18n.t(:label_add_projects) end end end diff --git a/app/views/admin/settings/project_custom_fields/project_mappings.html.erb b/app/views/admin/settings/project_custom_fields/project_mappings.html.erb index ae054b4369c..2c0091f80f6 100644 --- a/app/views/admin/settings/project_custom_fields/project_mappings.html.erb +++ b/app/views/admin/settings/project_custom_fields/project_mappings.html.erb @@ -39,18 +39,13 @@ See COPYRIGHT and LICENSE files for more details. <%= unless @custom_field.required? render(Primer::OpenProject::SubHeader.new(test_selector: "add-projects-sub-header")) do |component| - component.with_action_component do - render( - Primer::Beta::Button.new( - scheme: :primary, - tag: :a, - href: new_link_admin_settings_project_custom_field_path(@custom_field), - data: { controller: "async-dialog" } - ) - ) do |button| - button.with_leading_visual_icon(icon: "op-include-projects") - I18n.t(:label_add_projects) - end + component.with_action_button(scheme: :primary, + leading_icon: :"op-include-projects", + label: I18n.t(:label_add_projects), + tag: :a, + href: new_link_admin_settings_project_custom_field_path(@custom_field), + data: { controller: "async-dialog" }) do + I18n.t(:label_add_projects) end end end diff --git a/app/views/attribute_help_texts/index.html.erb b/app/views/attribute_help_texts/index.html.erb index 0d9acdf282d..9ffbb8195b1 100644 --- a/app/views/attribute_help_texts/index.html.erb +++ b/app/views/attribute_help_texts/index.html.erb @@ -48,13 +48,12 @@ See COPYRIGHT and LICENSE files for more details. render(Primer::OpenProject::SubHeader.new) do |subheader| subheader.with_action_button( scheme: :primary, - aria: { label: I18n.t("attribute_help_texts.add_new") }, - title: I18n.t("attribute_help_texts.add_new"), + leading_icon: :plus, + label: t(:"attribute_help_texts.add_new"), tag: :a, href: new_attribute_help_text_path(name: selected_tab(tabs)[:name]), test_selector: "attribute-help-texts--create-button" - ) do |button| - button.with_leading_visual_icon(icon: :plus) + ) do t("activerecord.models.attribute_help_text") end end diff --git a/app/views/colors/index.html.erb b/app/views/colors/index.html.erb index 417d32db5b1..5d143eb7bb2 100644 --- a/app/views/colors/index.html.erb +++ b/app/views/colors/index.html.erb @@ -42,12 +42,11 @@ See COPYRIGHT and LICENSE files for more details. render(Primer::OpenProject::SubHeader.new) do |subheader| subheader.with_action_button( scheme: :primary, - aria: { label: I18n.t("colors.index.label_new_color") }, - title: I18n.t("colors.index.label_new_color"), + leading_icon: :plus, + label: I18n.t("colors.index.label_new_color"), tag: :a, href: new_color_path - ) do |button| - button.with_leading_visual_icon(icon: :plus) + ) do t("activerecord.attributes.type.color") end end diff --git a/app/views/custom_actions/index.html.erb b/app/views/custom_actions/index.html.erb index 52ffc0c4cb6..48f4b54e7da 100644 --- a/app/views/custom_actions/index.html.erb +++ b/app/views/custom_actions/index.html.erb @@ -15,13 +15,12 @@ render(Primer::OpenProject::SubHeader.new) do |subheader| subheader.with_action_button( scheme: :primary, - aria: { label: I18n.t("custom_actions.new") }, - title: I18n.t("custom_actions.new"), + leading_icon: :plus, + label: t("custom_actions.new"), test_selector: "op-admin-custom-actions--button-new", tag: :a, href: new_custom_action_path - ) do |button| - button.with_leading_visual_icon(icon: :plus) + ) do CustomAction.model_name.human end end diff --git a/app/views/custom_fields/index.html.erb b/app/views/custom_fields/index.html.erb index 1d897f5a3b9..8ad43c64e81 100644 --- a/app/views/custom_fields/index.html.erb +++ b/app/views/custom_fields/index.html.erb @@ -35,12 +35,11 @@ See COPYRIGHT and LICENSE files for more details. render(Primer::OpenProject::SubHeader.new) do |subheader| subheader.with_action_button( scheme: :primary, - aria: { label: I18n.t(:label_custom_field_new) }, - title: I18n.t(:label_custom_field_new), + leading_icon: :plus, + label: t(:label_custom_field_new), tag: :a, href: new_custom_field_path(type: selected_tab(custom_fields_tabs)[:name]) - ) do |button| - button.with_leading_visual_icon(icon: :plus) + ) do t("activerecord.models.custom_field") end end diff --git a/app/views/forums/index.html.erb b/app/views/forums/index.html.erb index c60039082e0..12f9391ac4a 100644 --- a/app/views/forums/index.html.erb +++ b/app/views/forums/index.html.erb @@ -43,12 +43,11 @@ See COPYRIGHT and LICENSE files for more details. render(Primer::OpenProject::SubHeader.new) do |subheader| subheader.with_action_button( scheme: :primary, - aria: { label: t(:label_forum_new) }, - title: t(:label_forum_new), + leading_icon: :plus, + label: t(:label_forum_new), tag: :a, href: new_project_forum_path(@project) - ) do |button| - button.with_leading_visual_icon(icon: :plus) + ) do t("activerecord.models.forum") end end diff --git a/app/views/forums/show.html.erb b/app/views/forums/show.html.erb index baca2aa92d6..f696241a1cc 100644 --- a/app/views/forums/show.html.erb +++ b/app/views/forums/show.html.erb @@ -67,12 +67,11 @@ See COPYRIGHT and LICENSE files for more details. render(Primer::OpenProject::SubHeader.new) do |subheader| if authorize_for(:messages, :new) subheader.with_action_button(scheme: :primary, - aria: { label: t(:label_message_new) }, - title: t(:label_message_new), + leading_icon: :plus, + label: t(:label_message_new), tag: :a, class: "add-message-button", - href: url_for({ controller: "/messages", action: "new", forum_id: @forum })) do |button| - button.with_leading_visual_icon(icon: :plus) + href: url_for({ controller: "/messages", action: "new", forum_id: @forum })) do t(:label_message) end end diff --git a/app/views/groups/index.html.erb b/app/views/groups/index.html.erb index b20830cdb68..d7227ddc3ee 100644 --- a/app/views/groups/index.html.erb +++ b/app/views/groups/index.html.erb @@ -44,12 +44,11 @@ See COPYRIGHT and LICENSE files for more details. 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), + leading_icon: :plus, + label: t(:label_group_new), tag: :a, href: new_group_path - ) do |button| - button.with_leading_visual_icon(icon: :plus) + ) do t("activerecord.models.group") end end diff --git a/app/views/ldap_auth_sources/index.html.erb b/app/views/ldap_auth_sources/index.html.erb index da4281b01a9..303022b0837 100644 --- a/app/views/ldap_auth_sources/index.html.erb +++ b/app/views/ldap_auth_sources/index.html.erb @@ -44,13 +44,12 @@ See COPYRIGHT and LICENSE files for more details. render(Primer::OpenProject::SubHeader.new) do |subheader| subheader.with_action_button( scheme: :primary, - aria: { label: I18n.t(:label_ldap_auth_source_new) }, - title: I18n.t(:label_ldap_auth_source_new), + leading_icon: :plus, + label: t(:label_ldap_auth_source_new), tag: :a, test_selector: "op-admin-ldap-connection--button-new", href: new_ldap_auth_source_path - ) do |button| - button.with_leading_visual_icon(icon: :plus) + ) do t(:label_ldap_auth_source) end end diff --git a/app/views/news/index.html.erb b/app/views/news/index.html.erb index 8f83adecc4f..300d7425694 100644 --- a/app/views/news/index.html.erb +++ b/app/views/news/index.html.erb @@ -48,14 +48,13 @@ See COPYRIGHT and LICENSE files for more details. render(Primer::OpenProject::SubHeader.new) do |subheader| subheader.with_action_button( scheme: :primary, - aria: { label: t(:label_news_new) }, - title: I18n.t(:label_work_package_status_new), + leading_icon: :plus, + label: t(:label_news_new), tag: :a, id: "new_news_link", data: { "test-selector": "add-news-button" }, href: new_project_news_path(@project) - ) do |button| - button.with_leading_visual_icon(icon: :plus) + ) do t(:label_news_singular) end end diff --git a/app/views/oauth/applications/index.html.erb b/app/views/oauth/applications/index.html.erb index 73422fd0d23..220d6332460 100644 --- a/app/views/oauth/applications/index.html.erb +++ b/app/views/oauth/applications/index.html.erb @@ -42,13 +42,12 @@ See COPYRIGHT and LICENSE files for more details. render(Primer::OpenProject::SubHeader.new) do |subheader| subheader.with_action_button( scheme: :primary, - aria: { label: I18n.t("oauth.application.new") }, - title: I18n.t("oauth.application.new"), + leading_icon: :plus, + label: t("oauth.application.new"), tag: :a, test_selector: "op-admin-oauth--button-new", href: new_oauth_application_path - ) do |button| - button.with_leading_visual_icon(icon: :plus) + ) do t("oauth.application.singular") end end diff --git a/app/views/placeholder_users/index.html.erb b/app/views/placeholder_users/index.html.erb index 66faca63f07..d8b2ae5f1be 100644 --- a/app/views/placeholder_users/index.html.erb +++ b/app/views/placeholder_users/index.html.erb @@ -45,12 +45,11 @@ See COPYRIGHT and LICENSE files for more details. 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), + leading_icon: :plus, + label: t(:label_placeholder_user_new), tag: :a, href: new_placeholder_user_path - ) do |button| - button.with_leading_visual_icon(icon: :plus) + ) do t("activerecord.models.placeholder_user") end diff --git a/app/views/projects/settings/versions/show.html.erb b/app/views/projects/settings/versions/show.html.erb index b900c2f0cef..7ef7cd71788 100644 --- a/app/views/projects/settings/versions/show.html.erb +++ b/app/views/projects/settings/versions/show.html.erb @@ -41,12 +41,11 @@ See COPYRIGHT and LICENSE files for more details. <%= render(Primer::OpenProject::SubHeader.new) do |subheader| subheader.with_action_button( scheme: :primary, - aria: { label: t(:label_version_new) }, - title: t(:label_version_new), + leading_icon: :plus, + label: t(:label_version_new), tag: :a, href: url_for({ controller: "/versions", action: "new", project_id: @project }) - ) do |button| - button.with_leading_visual_icon(icon: :plus) + ) do t("activerecord.models.version") end end %> diff --git a/app/views/projects/settings/work_packages/categories/show.html.erb b/app/views/projects/settings/work_packages/categories/show.html.erb index 9a6844edba5..256b04a53e9 100644 --- a/app/views/projects/settings/work_packages/categories/show.html.erb +++ b/app/views/projects/settings/work_packages/categories/show.html.erb @@ -33,12 +33,11 @@ See COPYRIGHT and LICENSE files for more details. render(Primer::OpenProject::SubHeader.new) do |subheader| subheader.with_action_button( scheme: :primary, - aria: { label: t(:label_work_package_category_new) }, - title: t(:label_work_package_category_new), + leading_icon: :plus, + label: t(:label_work_package_category_new), tag: :a, href: url_for({ controller: "/categories", action: "new", project_id: @project }) - ) do |button| - button.with_leading_visual_icon(icon: :plus) + ) do t("activerecord.models.category") end end diff --git a/app/views/projects/settings/work_packages/custom_fields/show.html.erb b/app/views/projects/settings/work_packages/custom_fields/show.html.erb index c6ba05349b7..a5dc15346a1 100644 --- a/app/views/projects/settings/work_packages/custom_fields/show.html.erb +++ b/app/views/projects/settings/work_packages/custom_fields/show.html.erb @@ -34,12 +34,11 @@ See COPYRIGHT and LICENSE files for more details. render(Primer::OpenProject::SubHeader.new) do |subheader| subheader.with_action_button( scheme: :primary, - aria: { label: t(:label_custom_field_new) }, - title: I18n.t(:label_custom_field_new), + leading_icon: :plus, + label: t(:label_custom_field_new), tag: :a, href: new_custom_field_path(type: "WorkPackageCustomField") - ) do |button| - button.with_leading_visual_icon(icon: :plus) + ) do CustomField.model_name.human end end diff --git a/app/views/roles/index.html.erb b/app/views/roles/index.html.erb index 3c750339de2..c8fe30b9f6d 100644 --- a/app/views/roles/index.html.erb +++ b/app/views/roles/index.html.erb @@ -43,13 +43,12 @@ See COPYRIGHT and LICENSE files for more details. 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), + leading_icon: :plus, + label: t(:label_role_new), tag: :a, test_selector: "roles--create-button", href: new_role_path - ) do |button| - button.with_leading_visual_icon(icon: :plus) + ) do Role.model_name.human end end diff --git a/app/views/statuses/index.html.erb b/app/views/statuses/index.html.erb index 55af4507749..38dd5674038 100644 --- a/app/views/statuses/index.html.erb +++ b/app/views/statuses/index.html.erb @@ -43,12 +43,11 @@ See COPYRIGHT and LICENSE files for more details. render(Primer::OpenProject::SubHeader.new) do |subheader| subheader.with_action_button( scheme: :primary, - aria: { label: I18n.t(:label_work_package_status_new) }, - title: I18n.t(:label_work_package_status_new), + leading_icon: :plus, + label: t(:label_work_package_status_new), tag: :a, href: new_status_path - ) do |button| - button.with_leading_visual_icon(icon: :plus) + ) do t(:label_status) end end diff --git a/app/views/types/index.html.erb b/app/views/types/index.html.erb index fa22c743999..652c3374443 100644 --- a/app/views/types/index.html.erb +++ b/app/views/types/index.html.erb @@ -43,13 +43,12 @@ See COPYRIGHT and LICENSE files for more details. render(Primer::OpenProject::SubHeader.new) do |subheader| subheader.with_action_button( scheme: :primary, - aria: { label: I18n.t(:label_type_new) }, - title: I18n.t(:label_type_new), + leading_icon: :plus, + label: t(:label_type_new), test_selector: "op-admin-types--button-new", tag: :a, href: new_type_path - ) do |button| - button.with_leading_visual_icon(icon: :plus) + ) do t("activerecord.attributes.work_package.type") end end diff --git a/app/views/versions/index.html.erb b/app/views/versions/index.html.erb index 3651e156051..fa1f8e9bf3d 100644 --- a/app/views/versions/index.html.erb +++ b/app/views/versions/index.html.erb @@ -40,12 +40,11 @@ See COPYRIGHT and LICENSE files for more details. <%= render(Primer::OpenProject::SubHeader.new) do |subheader| subheader.with_action_button( scheme: :primary, - aria: { label: t(:label_version_new) }, - title: t(:label_version_new), + leading_icon: :plus, + label: t(:label_version_new), tag: :a, href: url_for({ controller: "/versions", action: "new", project_id: @project }) - ) do |button| - button.with_leading_visual_icon(icon: :plus) + ) do t("activerecord.models.version") end end %> diff --git a/config/routes.rb b/config/routes.rb index 1d8d02521ce..d5f23c73e73 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -590,6 +590,9 @@ Rails.application.routes.draw do put :move put :drop end + collection do + get :new_link + end end resource :working_days_and_hours, controller: "/admin/settings/working_days_and_hours_settings", only: %i[show update] resource :users, controller: "/admin/settings/users_settings", only: %i[show update] diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 12371adadc4..f0af61a599e 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -50,11 +50,11 @@ "@ngneat/content-loader": "^7.0.0", "@ngx-formly/core": "^6.1.4", "@openproject/octicons-angular": "^19.25.0", - "@openproject/primer-view-components": "^0.65.0", + "@openproject/primer-view-components": "^0.66.1", "@openproject/reactivestates": "^3.0.1", "@primer/css": "^21.5.0", "@primer/primitives": "^9.1.2", - "@primer/view-components": "npm:@openproject/primer-view-components@^0.65.0", + "@primer/view-components": "npm:@openproject/primer-view-components@^0.66.1", "@types/hotwired__turbo": "^8.0.1", "@uirouter/angular": "^13.0.0", "@uirouter/core": "^6.1.0", @@ -4738,9 +4738,9 @@ } }, "node_modules/@openproject/primer-view-components": { - "version": "0.65.0", - "resolved": "https://registry.npmjs.org/@openproject/primer-view-components/-/primer-view-components-0.65.0.tgz", - "integrity": "sha512-CSfkfz/cN6o8HRaIHeWGoca8Q8Bc0zA6BCcQNAd27mzbzcZlLWyoYcBiZe5625ch7Ku19cCmJKsN5b0OOVbjeg==", + "version": "0.66.1", + "resolved": "https://registry.npmjs.org/@openproject/primer-view-components/-/primer-view-components-0.66.1.tgz", + "integrity": "sha512-YME3MwSP9YSXNed875Fwz2eb0Y74p1vhUbyhcWfKmFcnN/butPsfeU2DELEuilg7K6BPk33Gf6TXQGI9DMeCww==", "dependencies": { "@github/auto-check-element": "^6.0.0", "@github/auto-complete-element": "^3.8.0", @@ -4835,9 +4835,9 @@ }, "node_modules/@primer/view-components": { "name": "@openproject/primer-view-components", - "version": "0.65.0", - "resolved": "https://registry.npmjs.org/@openproject/primer-view-components/-/primer-view-components-0.65.0.tgz", - "integrity": "sha512-CSfkfz/cN6o8HRaIHeWGoca8Q8Bc0zA6BCcQNAd27mzbzcZlLWyoYcBiZe5625ch7Ku19cCmJKsN5b0OOVbjeg==", + "version": "0.66.1", + "resolved": "https://registry.npmjs.org/@openproject/primer-view-components/-/primer-view-components-0.66.1.tgz", + "integrity": "sha512-YME3MwSP9YSXNed875Fwz2eb0Y74p1vhUbyhcWfKmFcnN/butPsfeU2DELEuilg7K6BPk33Gf6TXQGI9DMeCww==", "dependencies": { "@github/auto-check-element": "^6.0.0", "@github/auto-complete-element": "^3.8.0", @@ -25364,9 +25364,9 @@ } }, "@openproject/primer-view-components": { - "version": "0.65.0", - "resolved": "https://registry.npmjs.org/@openproject/primer-view-components/-/primer-view-components-0.65.0.tgz", - "integrity": "sha512-CSfkfz/cN6o8HRaIHeWGoca8Q8Bc0zA6BCcQNAd27mzbzcZlLWyoYcBiZe5625ch7Ku19cCmJKsN5b0OOVbjeg==", + "version": "0.66.1", + "resolved": "https://registry.npmjs.org/@openproject/primer-view-components/-/primer-view-components-0.66.1.tgz", + "integrity": "sha512-YME3MwSP9YSXNed875Fwz2eb0Y74p1vhUbyhcWfKmFcnN/butPsfeU2DELEuilg7K6BPk33Gf6TXQGI9DMeCww==", "requires": { "@github/auto-check-element": "^6.0.0", "@github/auto-complete-element": "^3.8.0", @@ -25439,9 +25439,9 @@ } }, "@primer/view-components": { - "version": "npm:@openproject/primer-view-components@0.65.0", - "resolved": "https://registry.npmjs.org/@openproject/primer-view-components/-/primer-view-components-0.65.0.tgz", - "integrity": "sha512-CSfkfz/cN6o8HRaIHeWGoca8Q8Bc0zA6BCcQNAd27mzbzcZlLWyoYcBiZe5625ch7Ku19cCmJKsN5b0OOVbjeg==", + "version": "npm:@openproject/primer-view-components@0.66.1", + "resolved": "https://registry.npmjs.org/@openproject/primer-view-components/-/primer-view-components-0.66.1.tgz", + "integrity": "sha512-YME3MwSP9YSXNed875Fwz2eb0Y74p1vhUbyhcWfKmFcnN/butPsfeU2DELEuilg7K6BPk33Gf6TXQGI9DMeCww==", "requires": { "@github/auto-check-element": "^6.0.0", "@github/auto-complete-element": "^3.8.0", diff --git a/frontend/package.json b/frontend/package.json index 48361e83ae8..254a7a4e721 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -102,11 +102,11 @@ "@ngneat/content-loader": "^7.0.0", "@ngx-formly/core": "^6.1.4", "@openproject/octicons-angular": "^19.25.0", - "@openproject/primer-view-components": "^0.65.0", + "@openproject/primer-view-components": "^0.66.1", "@openproject/reactivestates": "^3.0.1", "@primer/css": "^21.5.0", "@primer/primitives": "^9.1.2", - "@primer/view-components": "npm:@openproject/primer-view-components@^0.65.0", + "@primer/view-components": "npm:@openproject/primer-view-components@^0.66.1", "@types/hotwired__turbo": "^8.0.1", "@uirouter/angular": "^13.0.0", "@uirouter/core": "^6.1.0", diff --git a/lookbook/previews/open_project/common/sub_header_preview.rb b/lookbook/previews/open_project/common/sub_header_preview.rb index 129679bdb91..9b2996fb178 100644 --- a/lookbook/previews/open_project/common/sub_header_preview.rb +++ b/lookbook/previews/open_project/common/sub_header_preview.rb @@ -9,8 +9,11 @@ module OpenProject button.with_trailing_visual_counter(count: "15") "Filter" end - component.with_action_button(scheme: :primary) do |button| - button.with_leading_visual_icon(icon: :plus) + component.with_action_button( + leading_icon: :plus, + label: "New item", + scheme: :primary + ) do "Create" end end @@ -34,8 +37,11 @@ module OpenProject component.with_text { text } unless text.nil? if show_action_button - component.with_action_button(scheme: :primary) do |button| - button.with_leading_visual_icon(icon: :plus) + component.with_action_button( + leading_icon: :plus, + label: "New item", + scheme: :primary + ) do "Create" end end diff --git a/modules/auth_saml/app/views/saml/providers/index.html.erb b/modules/auth_saml/app/views/saml/providers/index.html.erb index 30602bf0771..dc3e7ef4c82 100644 --- a/modules/auth_saml/app/views/saml/providers/index.html.erb +++ b/modules/auth_saml/app/views/saml/providers/index.html.erb @@ -12,13 +12,12 @@ <%= render(Primer::OpenProject::SubHeader.new) do |subheader| subheader.with_action_button( scheme: :primary, - aria: { label: I18n.t("saml.providers.label_add_new") }, - title: I18n.t("saml.providers.label_add_new"), + leading_icon: :plus, + label: I18n.t("saml.providers.label_add_new"), tag: :a, disabled: !EnterpriseToken.allows_to?(:sso_auth_providers), href: new_saml_provider_path - ) do |button| - button.with_leading_visual_icon(icon: :plus) + ) do t("saml.providers.singular") end end %> diff --git a/modules/backlogs/app/views/rb_master_backlogs/index.html.erb b/modules/backlogs/app/views/rb_master_backlogs/index.html.erb index b13d51be3df..0ecc2ab079a 100644 --- a/modules/backlogs/app/views/rb_master_backlogs/index.html.erb +++ b/modules/backlogs/app/views/rb_master_backlogs/index.html.erb @@ -43,12 +43,11 @@ See COPYRIGHT and LICENSE files for more details. <%= render(Primer::OpenProject::SubHeader.new) do |subheader| subheader.with_action_button( scheme: :primary, - aria: { label: t(:label_version_new) }, - title: t(:label_version_new), + leading_icon: :plus, + label: I18n.t(:label_version_new), tag: :a, href: url_for({ controller: "/versions", action: "new", project_id: @project }) - ) do |button| - button.with_leading_visual_icon(icon: :plus) + ) do t("activerecord.models.version") end end %> diff --git a/modules/bim/app/views/bim/ifc_models/ifc_models/index.html.erb b/modules/bim/app/views/bim/ifc_models/ifc_models/index.html.erb index 3bf76262f6b..10c8048162d 100644 --- a/modules/bim/app/views/bim/ifc_models/ifc_models/index.html.erb +++ b/modules/bim/app/views/bim/ifc_models/ifc_models/index.html.erb @@ -57,13 +57,12 @@ See COPYRIGHT and LICENSE files for more details. render(Primer::OpenProject::SubHeader.new) do |subheader| subheader.with_action_button( scheme: :primary, - aria: { label: I18n.t("ifc_models.label_new_ifc_model") }, + leading_icon: :plus, + label: I18n.t("ifc_models.label_new_ifc_model"), data: { test_selector: "ifc-create-button" }, - title: I18n.t("ifc_models.label_new_ifc_model"), tag: :a, href: new_bcf_project_ifc_model_path - ) do |button| - button.with_leading_visual_icon(icon: :plus) + ) do ::Bim::IfcModels::IfcModel.model_name.human end end diff --git a/modules/boards/app/views/boards/boards/index.html.erb b/modules/boards/app/views/boards/boards/index.html.erb index a20e1985894..75e4440e778 100644 --- a/modules/boards/app/views/boards/boards/index.html.erb +++ b/modules/boards/app/views/boards/boards/index.html.erb @@ -42,9 +42,7 @@ See COPYRIGHT and LICENSE files for more details. <%= render Primer::OpenProject::SubHeader.new do |subheader| - subheader.with_action_component do - render Boards::AddButtonComponent.new(current_project: @project) - end + render Boards::AddButtonComponent.new(subheader:, current_project: @project) end %> diff --git a/modules/budgets/app/views/budgets/index.html.erb b/modules/budgets/app/views/budgets/index.html.erb index 9fe2557595f..eff9b5a1f10 100644 --- a/modules/budgets/app/views/budgets/index.html.erb +++ b/modules/budgets/app/views/budgets/index.html.erb @@ -41,13 +41,12 @@ See COPYRIGHT and LICENSE files for more details. render(Primer::OpenProject::SubHeader.new) do |subheader| subheader.with_action_button( scheme: :primary, - aria: { label: I18n.t(:button_add_budget) }, + leading_icon: :plus, + label: I18n.t(:button_add_budget), data: { test_selector: "budget-create-button" }, - title: I18n.t(:button_add_budget), tag: :a, href: new_projects_budget_path(@project) - ) do |button| - button.with_leading_visual_icon(icon: :plus) + ) do t(:label_budget) end end diff --git a/modules/calendar/app/views/calendar/calendars/index.html.erb b/modules/calendar/app/views/calendar/calendars/index.html.erb index a345ed9930a..cf97456f90d 100644 --- a/modules/calendar/app/views/calendar/calendars/index.html.erb +++ b/modules/calendar/app/views/calendar/calendars/index.html.erb @@ -41,9 +41,7 @@ See COPYRIGHT and LICENSE files for more details. <%= render Primer::OpenProject::SubHeader.new do |subheader| - subheader.with_action_component do - render Calendar::AddButtonComponent.new(current_project: @project) - end + render Calendar::AddButtonComponent.new(subheader:, current_project: @project) end %> diff --git a/modules/costs/app/components/my/time_tracking/sub_header_component.html.erb b/modules/costs/app/components/my/time_tracking/sub_header_component.html.erb index cfa2a6e89ba..af5815cdcb7 100644 --- a/modules/costs/app/components/my/time_tracking/sub_header_component.html.erb +++ b/modules/costs/app/components/my/time_tracking/sub_header_component.html.erb @@ -5,26 +5,26 @@ component.with_text { title } - component.with_action_component do - render(Primer::Beta::ButtonGroup.new) do |group| - group.with_button(icon: "arrow-left", tag: :a, **previous_attrs) - group.with_button(icon: "arrow-right", tag: :a, **next_attrs) - end + component.with_action_button_group do |group| + group.with_button(icon: "arrow-left", tag: :a, **previous_attrs) + group.with_button(icon: "arrow-right", tag: :a, **next_attrs) end - component.with_action_button(tag: :a, href: today_href) do |button| - button.with_leading_visual_icon(icon: "op-calendar-day") + component.with_action_button(tag: :a, + href: today_href, + leading_icon: :"op-calendar-day", + label: I18n.t(:label_today)) do I18n.t(:label_today_capitalized) end component.with_action_button( scheme: :primary, + leading_icon: :plus, + label: I18n.t(:button_log_time), data: { "turbo-stream" => true }, - aria: { "label" => t(:button_log_time) }, tag: :a, href: dialog_time_entries_path(onlyMe: true, date: date.iso8601) - ) do |button| - button.with_leading_visual_icon(icon: "plus") + ) do t(:button_add_time_entry) end end %> diff --git a/modules/costs/app/views/admin/cost_types/index.html.erb b/modules/costs/app/views/admin/cost_types/index.html.erb index 86186af349d..1e46956427b 100644 --- a/modules/costs/app/views/admin/cost_types/index.html.erb +++ b/modules/costs/app/views/admin/cost_types/index.html.erb @@ -45,12 +45,11 @@ See COPYRIGHT and LICENSE files for more details. <%= 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), + leading_icon: :plus, + label: I18n.t(:button_add_cost_type), tag: :a, href: new_admin_cost_type_path - ) do |button| - button.with_leading_visual_icon(icon: :plus) + ) do CostType.model_name.human end %> diff --git a/modules/documents/app/views/documents/index.html.erb b/modules/documents/app/views/documents/index.html.erb index 06ddb7df9f2..61a41ebaab6 100644 --- a/modules/documents/app/views/documents/index.html.erb +++ b/modules/documents/app/views/documents/index.html.erb @@ -42,12 +42,11 @@ See COPYRIGHT and LICENSE files for more details. render(Primer::OpenProject::SubHeader.new) do |subheader| subheader.with_action_button( scheme: :primary, - aria: { label: t(:label_document_new) }, - title: t(:label_document_new), + leading_icon: :plus, + label: I18n.t(:label_document_new), tag: :a, href: url_for({ controller: "/documents", action: "new", project_id: @project }) - ) do |button| - button.with_leading_visual_icon(icon: :plus) + ) do t("activerecord.models.document") end end diff --git a/modules/github_integration/app/views/deploy_targets/index.html.erb b/modules/github_integration/app/views/deploy_targets/index.html.erb index f90897b8ea9..3cfc21201ab 100644 --- a/modules/github_integration/app/views/deploy_targets/index.html.erb +++ b/modules/github_integration/app/views/deploy_targets/index.html.erb @@ -43,12 +43,11 @@ See COPYRIGHT and LICENSE files for more details. render(Primer::OpenProject::SubHeader.new) do |subheader| subheader.with_action_button( scheme: :primary, - aria: { label: I18n.t(:button_add_deploy_target) }, - title: I18n.t(:button_add_deploy_target), + leading_icon: :plus, + label: I18n.t(:button_add_deploy_target), tag: :a, href: new_deploy_target_path - ) do |button| - button.with_leading_visual_icon(icon: :plus) + ) do t(:label_deploy_target) end end diff --git a/modules/ldap_groups/app/views/ldap_groups/synchronized_groups/index.html.erb b/modules/ldap_groups/app/views/ldap_groups/synchronized_groups/index.html.erb index 04a5ecff07f..fa65ce39ffb 100644 --- a/modules/ldap_groups/app/views/ldap_groups/synchronized_groups/index.html.erb +++ b/modules/ldap_groups/app/views/ldap_groups/synchronized_groups/index.html.erb @@ -12,30 +12,24 @@ %> <%= render(Primer::OpenProject::SubHeader.new) do |subheader| - subheader.with_action_component do - render(Primer::Alpha::ActionMenu.new(anchor_align: :end)) do |menu| - menu.with_show_button( - scheme: :primary, - test_selector: "op-admin-synchronized-groups--button-new", - aria: { label: I18n.t(:button_add) } - ) do |button| - button.with_leading_visual_icon(icon: :plus) - button.with_trailing_action_icon(icon: :"triangle-down") - I18n.t(:button_add) - end + subheader.with_action_menu(leading_icon: :plus, + trailing_icon: :"triangle-down", + label: I18n.t(:button_add), + anchor_align: :end, + button_arguments: { scheme: :primary, + aria: { label: I18n.t(:button_add) }, + test_selector: "op-admin-synchronized-groups--button-new" }) do |menu| + menu.with_item( + label: I18n.t("ldap_groups.synchronized_filters.singular"), + test_selector: "op-admin-synchronized-groups--new-filters", + href: new_ldap_groups_synchronized_filter_path + ) - menu.with_item( - label: I18n.t("ldap_groups.synchronized_filters.singular"), - test_selector: "op-admin-synchronized-groups--new-filters", - href: new_ldap_groups_synchronized_filter_path - ) - - menu.with_item( - label: I18n.t("ldap_groups.synchronized_groups.singular"), - test_selector: "op-admin-synchronized-groups--new-groups", - href: new_ldap_groups_synchronized_group_path - ) - end + menu.with_item( + label: I18n.t("ldap_groups.synchronized_groups.singular"), + test_selector: "op-admin-synchronized-groups--new-groups", + href: new_ldap_groups_synchronized_group_path + ) end end %> diff --git a/modules/meeting/app/components/meetings/combined_filter_component.html.erb b/modules/meeting/app/components/meetings/combined_filter_component.html.erb deleted file mode 100644 index 762b7c82772..00000000000 --- a/modules/meeting/app/components/meetings/combined_filter_component.html.erb +++ /dev/null @@ -1,28 +0,0 @@ -<%= - flex_layout do |flex| - flex.with_column do - render(Meetings::MeetingFilterButtonComponent.new(query: @query, project: @project)) - end - - flex.with_column(ml: 1) do - render(Primer::Alpha::SegmentedControl.new("aria-label": I18n.t(:label_meeting_date_time))) do |control| - control.with_item( - tag: :a, - icon: :"arrow-right", - href: dynamic_path, - label: t(:label_upcoming_meetings_short), - title: t(:label_upcoming_meetings), - selected: upcoming_query? - ) - control.with_item( - tag: :a, - icon: :history, - href: dynamic_path(upcoming: false), - label: t(:label_past_meetings_short), - title: t(:label_past_meetings), - selected: !upcoming_query? - ) - end - end - end -%> diff --git a/modules/meeting/app/components/meetings/index_sub_header_component.html.erb b/modules/meeting/app/components/meetings/index_sub_header_component.html.erb index da37ddc4d52..f465f403f9e 100644 --- a/modules/meeting/app/components/meetings/index_sub_header_component.html.erb +++ b/modules/meeting/app/components/meetings/index_sub_header_component.html.erb @@ -8,43 +8,54 @@ ) ) do |subheader| subheader.with_filter_component do - render(Meetings::CombinedFilterComponent.new(query: @query, project: @project, params: @params)) + render(Meetings::MeetingFilterButtonComponent.new(query: @query, project: @project)) + end + + subheader.with_segmented_control("aria-label": I18n.t(:label_meeting_date_time)) do |control| + control.with_item( + tag: :a, + icon: :"arrow-right", + href: dynamic_path, + label: t(:label_upcoming_meetings_short), + title: t(:label_upcoming_meetings), + selected: upcoming_query? + ) + control.with_item( + tag: :a, + icon: :history, + href: dynamic_path(upcoming: false), + label: t(:label_past_meetings_short), + title: t(:label_past_meetings), + selected: !upcoming_query? + ) end if render_create_button? - subheader.with_action_component do - render Primer::Alpha::ActionMenu.new(anchor_align: :end, size: :small) do |menu| - menu.with_show_button( - scheme: :primary, - test_selector: "add-meeting-button", - mobile_icon: :plus, - mobile_label: label_text, - id: id, - title: accessibility_label_text, - aria: { label: accessibility_label_text } - ) do |button| - button.with_leading_visual_icon(icon: :plus) - button.with_trailing_action_icon(icon: :"triangle-down") - I18n.t(:label_meeting) - end + subheader.with_action_menu(leading_icon: :plus, + trailing_icon: :"triangle-down", + label: label_text, + anchor_align: :end, + size: :small, + button_arguments: { scheme: :primary, + id: id, + aria: { label: accessibility_label_text }, + test_selector: "add-meeting-button" }) do |menu| + menu.with_item( + label: I18n.t("meeting.types.one_time"), + tag: :a, + href: polymorphic_path([:new_dialog, @project, :meetings]), + content_arguments: { data: { controller: "async-dialog" } } + ) do |item| + item.with_description.with_content(t("meeting.types.structured_text")) + end - menu.with_item( - label: I18n.t("meeting.types.one_time"), - tag: :a, - href: polymorphic_path([:new_dialog, @project, :meetings]), - content_arguments: { data: { controller: "async-dialog" } } - ) do |item| - item.with_description.with_content(t("meeting.types.structured_text")) - end - - menu.with_item( - label: I18n.t("meeting.types.recurring"), - tag: :a, - href: polymorphic_path([:new_dialog, @project, :meetings], type: :recurring), - content_arguments: { data: { controller: "async-dialog" } } - ) do |item| - item.with_description.with_content(t("meeting.types.recurring_text")) - end + menu.with_item( + label: I18n.t("meeting.types.recurring"), + tag: :a, + href: polymorphic_path([:new_dialog, @project, :meetings], type: :recurring), + content_arguments: { data: { controller: "async-dialog" } } + ) do |item| + item.with_description.with_content(t("meeting.types.recurring_text")) end end end diff --git a/modules/meeting/app/components/meetings/index_sub_header_component.rb b/modules/meeting/app/components/meetings/index_sub_header_component.rb index 1be28c8987c..41aa0a3ef0d 100644 --- a/modules/meeting/app/components/meetings/index_sub_header_component.rb +++ b/modules/meeting/app/components/meetings/index_sub_header_component.rb @@ -49,10 +49,6 @@ module Meetings end end - def dynamic_path - polymorphic_path([:new, @project, :meeting]) - end - def id "add-meeting-button" end @@ -64,5 +60,18 @@ module Meetings def label_text I18n.t(:label_meeting) end + + def upcoming_query? + filter = @query.filters.find { |f| f.name == :time } + filter ? !filter.past? : true + end + + def dynamic_path(upcoming: true) + polymorphic_path([@project, :meetings], current_params.merge(upcoming:)) + end + + def current_params + @current_params ||= params.slice(:filters, :page, :per_page).permit! + end end end diff --git a/modules/meeting/app/components/recurring_meetings/show_page_sub_header_component.html.erb b/modules/meeting/app/components/recurring_meetings/show_page_sub_header_component.html.erb index fed0997333d..8f356a556aa 100644 --- a/modules/meeting/app/components/recurring_meetings/show_page_sub_header_component.html.erb +++ b/modules/meeting/app/components/recurring_meetings/show_page_sub_header_component.html.erb @@ -1,22 +1,22 @@ -<%= render(Primer::OpenProject::SubHeader.new) do |subheader| - subheader.with_filter_component do - render(Primer::Alpha::SegmentedControl.new("aria-label": I18n.t(:label_filter_plural))) do |control| - control.with_item( - tag: :a, - icon: :"arrow-right", - href: project_recurring_meeting_path(@meeting.project, @meeting), - label: t(:label_upcoming_meetings_short), - title: t(:label_upcoming_meetings), - selected: @params[:direction] != "past" - ) - control.with_item( - tag: :a, - icon: :history, - href: project_recurring_meeting_path(@meeting.project, @meeting, direction: :past), - label: t(:label_past_meetings_short), - title: t(:label_past_meetings), - selected: @params[:direction] == "past" - ) - end - end - end %> +<%= + render(Primer::OpenProject::SubHeader.new) do |subheader| + subheader.with_segmented_control("aria-label": I18n.t(:label_filter_plural)) do |control| + control.with_item( + tag: :a, + icon: :"arrow-right", + href: project_recurring_meeting_path(@meeting.project, @meeting), + label: t(:label_upcoming_meetings_short), + title: t(:label_upcoming_meetings), + selected: @params[:direction] != "past" + ) + control.with_item( + tag: :a, + icon: :history, + href: project_recurring_meeting_path(@meeting.project, @meeting, direction: :past), + label: t(:label_past_meetings_short), + title: t(:label_past_meetings), + selected: @params[:direction] == "past" + ) + end + end +%> diff --git a/modules/openid_connect/app/views/openid_connect/providers/index.html.erb b/modules/openid_connect/app/views/openid_connect/providers/index.html.erb index dcb13d7d67d..fc181f852f3 100644 --- a/modules/openid_connect/app/views/openid_connect/providers/index.html.erb +++ b/modules/openid_connect/app/views/openid_connect/providers/index.html.erb @@ -13,28 +13,18 @@ <%= render(Primer::OpenProject::SubHeader.new) do |subheader| - subheader.with_action_component do - render( - Primer::Alpha::ActionMenu.new( - anchor_align: :end + subheader.with_action_menu(leading_icon: :plus, + trailing_icon: :"triangle-down", + label: I18n.t("openid_connect.providers.singular"), + anchor_align: :end, + button_arguments: { scheme: :primary, + disabled: !EnterpriseToken.allows_to?(:sso_auth_providers), + aria: { label: I18n.t("openid_connect.providers.label_add_new") } }) do |menu| + OpenIDConnect::Provider::OIDC_PROVIDERS.each do |provider_type| + menu.with_item( + label: I18n.t("openid_connect.providers.#{provider_type}.name"), + href: url_helpers.new_openid_connect_provider_path(oidc_provider: provider_type) ) - ) do |menu| - menu.with_show_button( - scheme: :primary, - disabled: !EnterpriseToken.allows_to?(:sso_auth_providers), - aria: { label: I18n.t("openid_connect.providers.label_add_new") } - ) do |button| - button.with_leading_visual_icon(icon: :plus) - button.with_trailing_action_icon(icon: :"triangle-down") - I18n.t("openid_connect.providers.singular") - end - - OpenIDConnect::Provider::OIDC_PROVIDERS.each do |provider_type| - menu.with_item( - label: I18n.t("openid_connect.providers.#{provider_type}.name"), - href: url_helpers.new_openid_connect_provider_path(oidc_provider: provider_type) - ) - end end end end diff --git a/modules/storages/app/views/storages/admin/health_status/show.html.erb b/modules/storages/app/views/storages/admin/health_status/show.html.erb index 8f81ba1508f..e1e3e1e6191 100644 --- a/modules/storages/app/views/storages/admin/health_status/show.html.erb +++ b/modules/storages/app/views/storages/admin/health_status/show.html.erb @@ -61,21 +61,22 @@ See COPYRIGHT and LICENSE files for more details. render(Primer::OpenProject::SubHeader.new) do |subheader| subheader.with_action_button( scheme: :secondary, + leading_icon: :download, + label: download_label, tag: :a, href: admin_settings_storage_health_status_report_path(@storage, format: :txt), data: { turbo: true }, - aria: { label: download_label } - ) do |button| - button.with_leading_visual_icon(icon: :download) + ) do download_label end subheader.with_action_button( scheme: :primary, + leading_icon: :plus, + label: button_label, tag: :a, href: admin_settings_storage_health_status_report_path(@storage), data: { turbo_method: :post, turbo: true }, - aria: { label: button_label } ) do button_label end diff --git a/modules/storages/app/views/storages/admin/storages/index.html.erb b/modules/storages/app/views/storages/admin/storages/index.html.erb index 5b5f4c436ec..24da22ddbb9 100644 --- a/modules/storages/app/views/storages/admin/storages/index.html.erb +++ b/modules/storages/app/views/storages/admin/storages/index.html.erb @@ -16,29 +16,26 @@ end %> <% end %> <%= render(Primer::OpenProject::SubHeader.new) do |subheader| - subheader.with_action_component do - render(Primer::Alpha::ActionMenu.new(test_selector: 'storages-select-provider-action-menu', - anchor_align: :end)) do |menu| - menu.with_show_button(scheme: :primary, - aria: { label: I18n.t("storages.label_add_new_storage") }, - test_selector: "storages-create-new-provider-button") do |button| - button.with_leading_visual_icon(icon: :plus) - button.with_trailing_action_icon(icon: :"triangle-down") - I18n.t("storages.label_storage") - end + subheader.with_action_menu(leading_icon: :plus, + trailing_icon: :"triangle-down", + label: I18n.t("storages.label_storage"), + test_selector: 'storages-select-provider-action-menu', + anchor_align: :end, + button_arguments: { scheme: :primary, + aria: { label: I18n.t("storages.label_add_new_storage") }, + test_selector: "storages-create-new-provider-button"}) do |menu| - ::Storages::Storage::PROVIDER_TYPES.each do |provider_type| - short_provider_type = ::Storages::Storage.shorten_provider_type(provider_type) + ::Storages::Storage::PROVIDER_TYPES.each do |provider_type| + short_provider_type = ::Storages::Storage.shorten_provider_type(provider_type) - menu.with_item( - label: I18n.t("storages.provider_types.#{short_provider_type}.name"), - href: url_helpers.new_admin_settings_storage_path(provider: short_provider_type) - ) do |item| - item.with_trailing_visual_icon( - icon: "op-enterprise-addons", - classes: "upsell-colored" - ) if ::Storages::Storage::one_drive_without_ee_token?(provider_type) - end + menu.with_item( + label: I18n.t("storages.provider_types.#{short_provider_type}.name"), + href: url_helpers.new_admin_settings_storage_path(provider: short_provider_type) + ) do |item| + item.with_trailing_visual_icon( + icon: "op-enterprise-addons", + classes: "upsell-colored" + ) if ::Storages::Storage::one_drive_without_ee_token?(provider_type) end end end diff --git a/modules/storages/app/views/storages/admin/storages/project_storages/index.html.erb b/modules/storages/app/views/storages/admin/storages/project_storages/index.html.erb index b38cf98e397..8adaabec2a9 100644 --- a/modules/storages/app/views/storages/admin/storages/project_storages/index.html.erb +++ b/modules/storages/app/views/storages/admin/storages/project_storages/index.html.erb @@ -34,18 +34,13 @@ See COPYRIGHT and LICENSE files for more details. <%= if @storage.configured? render(Primer::OpenProject::SubHeader.new) do |component| - component.with_action_component do - render( - Primer::Beta::Button.new( - scheme: :primary, - tag: :a, - href: new_admin_settings_storage_project_storage_path(@storage), - data: { controller: "async-dialog" } - ) - ) do |button| - button.with_leading_visual_icon(icon: "op-include-projects") - I18n.t(:label_add_projects) - end + component.with_action_button(scheme: :primary, + leading_icon: :"op-include-projects", + label: I18n.t(:label_add_projects), + tag: :a, + href: new_admin_settings_storage_project_storage_path(@storage), + data: { controller: "async-dialog" }) do + I18n.t(:label_add_projects) end end end diff --git a/modules/team_planner/app/views/team_planner/team_planner/index.html.erb b/modules/team_planner/app/views/team_planner/team_planner/index.html.erb index a29116913b3..e8aa444f5fe 100644 --- a/modules/team_planner/app/views/team_planner/team_planner/index.html.erb +++ b/modules/team_planner/app/views/team_planner/team_planner/index.html.erb @@ -12,9 +12,7 @@ <%= render Primer::OpenProject::SubHeader.new do |subheader| - subheader.with_action_component do - render ::TeamPlanner::AddButtonComponent.new(current_project: @project) - end + render ::TeamPlanner::AddButtonComponent.new(subheader:, current_project: @project) end %> diff --git a/modules/team_planner/app/views/team_planner/team_planner/overview.html.erb b/modules/team_planner/app/views/team_planner/team_planner/overview.html.erb index 7d64888acaa..d38e1cf1a45 100644 --- a/modules/team_planner/app/views/team_planner/team_planner/overview.html.erb +++ b/modules/team_planner/app/views/team_planner/team_planner/overview.html.erb @@ -11,9 +11,7 @@ <%= render Primer::OpenProject::SubHeader.new do |subheader| - subheader.with_action_component do - render ::TeamPlanner::AddButtonComponent.new - end + render ::TeamPlanner::AddButtonComponent.new(subheader:) end %> diff --git a/modules/two_factor_authentication/app/views/two_factor_authentication/my/two_factor_devices/index.html.erb b/modules/two_factor_authentication/app/views/two_factor_authentication/my/two_factor_devices/index.html.erb index 45ad95e3073..7f4fcb314f5 100644 --- a/modules/two_factor_authentication/app/views/two_factor_authentication/my/two_factor_devices/index.html.erb +++ b/modules/two_factor_authentication/app/views/two_factor_authentication/my/two_factor_devices/index.html.erb @@ -11,26 +11,21 @@ %> <%= render(Primer::OpenProject::SubHeader.new) do |subheader| - subheader.with_action_component do - render(Primer::Alpha::ActionMenu.new(anchor_align: :end, size: :small)) do |menu| - menu.with_show_button( - scheme: :primary, - test_selector: "two_factor_authentication_devices_button", - aria: { label: t("two_factor_authentication.label_device") } - ) do |button| - button.with_leading_visual_icon(icon: :plus) - button.with_trailing_action_icon(icon: :"triangle-down") - t("two_factor_authentication.label_device") - end - - @available_devices.each_key do |key| - menu.with_item( - label: t("two_factor_authentication.devices.#{key}.title"), - href: url_for(action: :new, type: key), - test_selector: "two_factor_authentication_devices_#{key}" - ) do |item| - item.with_description.with_content(t("two_factor_authentication.devices.#{key}.description")) - end + subheader.with_action_menu(leading_icon: :plus, + trailing_icon: :"triangle-down", + label: t("two_factor_authentication.label_device"), + anchor_align: :end, + size: :small, + button_arguments: { scheme: :primary, + test_selector: "two_factor_authentication_devices_button", + aria: { label: t("two_factor_authentication.label_device") } }) do |menu| + @available_devices.each_key do |key| + menu.with_item( + label: t("two_factor_authentication.devices.#{key}.title"), + href: url_for(action: :new, type: key), + test_selector: "two_factor_authentication_devices_#{key}" + ) do |item| + item.with_description.with_content(t("two_factor_authentication.devices.#{key}.description")) end end end diff --git a/modules/webhooks/app/views/webhooks/outgoing/admin/index.html.erb b/modules/webhooks/app/views/webhooks/outgoing/admin/index.html.erb index 7fd432b73ae..f4dac95eab4 100644 --- a/modules/webhooks/app/views/webhooks/outgoing/admin/index.html.erb +++ b/modules/webhooks/app/views/webhooks/outgoing/admin/index.html.erb @@ -15,12 +15,11 @@ render(Primer::OpenProject::SubHeader.new) do |subheader| subheader.with_action_button( scheme: :primary, - aria: { label: I18n.t("webhooks.outgoing.label_add_new") }, - title: I18n.t("webhooks.outgoing.label_add_new"), + leading_icon: :plus, + label: I18n.t("webhooks.outgoing.label_add_new"), tag: :a, href: new_admin_outgoing_webhook_path - ) do |button| - button.with_leading_visual_icon(icon: :plus) + ) do t("webhooks.singular") end end