diff --git a/app/components/work_packages/activities_tab/journals/item_component/add_reactions.html.erb b/app/components/work_packages/activities_tab/journals/item_component/add_reactions.html.erb index 56db19bbed56..233c6b9b2fba 100644 --- a/app/components/work_packages/activities_tab/journals/item_component/add_reactions.html.erb +++ b/app/components/work_packages/activities_tab/journals/item_component/add_reactions.html.erb @@ -1,47 +1,33 @@ <%= - component_wrapper do - render( - Primer::Alpha::Overlay.new( - title: I18n.t("reactions.action_title"), - padding: :condensed, - anchor_side: :outside_top, - visually_hide_title: true - ) - ) do |overlay| - overlay.with_show_button( - icon: "smiley", - "aria-label": I18n.t("reactions.add_reaction"), - name: I18n.t("reactions.add_reaction"), - mr: 1, - test_selector: "add-reactions-button" - ) - - overlay.with_body(pt: 2, test_selector: "emoji-reactions-overlay") do - flex_layout(flex_wrap: :wrap, classes: "op-add-reactions-overlay") do |add_reactions_container| - EmojiReaction.available_emoji_reactions.each do |emoji, reaction| - add_reactions_container.with_column(mr: 1) do - render( - Primer::Beta::Button.new( - scheme: button_scheme(reaction), - color: :default, - bg: counter_color(reaction), - id: "overlay-#{journal.id}-#{reaction}", - test_selector: "overlay-reaction-#{reaction}", - tag: :a, - href: href(reaction:), - data: { - turbo_stream: true, - turbo_method: :put, - "#{polling_stimulus_controller}-target": "reactionButton" - }, - aria: { label: I18n.t("reactions.react_with", reaction: reaction.to_s.humanize(capitalize: false)) }, - font_size: 4, - classes: "op-add-reactions-button" - ) - ) do - emoji - end - end + component_wrapper(menu_id:) do + flex_layout( + flex_wrap: :wrap, + test_selector: "emoji-reactions-overlay", + classes: "op-add-reactions-overlay", + p: 2 + ) do |add_reactions_container| + EmojiReaction.available_emoji_reactions.each do |emoji, reaction| + add_reactions_container.with_column(mr: 1) do + render( + Primer::Beta::Button.new( + scheme: button_scheme(reaction), + color: :default, + bg: counter_color(reaction), + id: "overlay-#{journal.id}-#{reaction}", + test_selector: "overlay-reaction-#{reaction}", + tag: :a, + href: href(reaction:), + data: { + turbo_stream: true, + turbo_method: :put, + "#{polling_stimulus_controller}-target": "reactionButton" + }, + aria: { label: I18n.t("reactions.react_with", reaction: reaction.to_s.humanize(capitalize: false)) }, + font_size: 4, + classes: "op-add-reactions-button" + ) + ) do + emoji end end end diff --git a/app/components/work_packages/activities_tab/journals/item_component/add_reactions.rb b/app/components/work_packages/activities_tab/journals/item_component/add_reactions.rb index a784a1bd3ff9..c42a82c3c894 100644 --- a/app/components/work_packages/activities_tab/journals/item_component/add_reactions.rb +++ b/app/components/work_packages/activities_tab/journals/item_component/add_reactions.rb @@ -44,6 +44,14 @@ def initialize(journal:, grouped_emoji_reactions:) @grouped_emoji_reactions = grouped_emoji_reactions || {} end + def self.menu_id(journal) + "reactions-menu-#{journal.id}" + end + + def menu_id + self.class.menu_id(journal) + end + def render? current_user_can_react? end diff --git a/app/components/work_packages/activities_tab/journals/item_component/show.html.erb b/app/components/work_packages/activities_tab/journals/item_component/show.html.erb index eae85d2671a2..60e70dfff555 100644 --- a/app/components/work_packages/activities_tab/journals/item_component/show.html.erb +++ b/app/components/work_packages/activities_tab/journals/item_component/show.html.erb @@ -9,7 +9,27 @@ end journal_container.with_row(flex_layout: true) do |reactions_container| reactions_container.with_column do - render(WorkPackages::ActivitiesTab::Journals::ItemComponent::AddReactions.new(journal:, grouped_emoji_reactions:)) + if reactable? + render( + Primer::Alpha::ActionMenu.new( + menu_id:, + anchor_side: :outside_top, + overlay_arguments: { + title: I18n.t("reactions.action_title"), + visually_hide_title: true + }, + src: emoji_actions_work_package_activity_path(journal.journable, journal) + ) + ) do |action_menu| + action_menu.with_show_button( + icon: "smiley", + "aria-label": I18n.t("reactions.add_reaction"), + name: I18n.t("reactions.add_reaction"), + mr: 1, + test_selector: "add-reactions-button" + ) + end + end end reactions_container.with_column do render(WorkPackages::ActivitiesTab::Journals::ItemComponent::Reactions.new(journal:, grouped_emoji_reactions:)) diff --git a/app/components/work_packages/activities_tab/journals/item_component/show.rb b/app/components/work_packages/activities_tab/journals/item_component/show.rb index cfacea9894ff..b981eed7aed5 100644 --- a/app/components/work_packages/activities_tab/journals/item_component/show.rb +++ b/app/components/work_packages/activities_tab/journals/item_component/show.rb @@ -46,6 +46,14 @@ def initialize(journal:, filter:, grouped_emoji_reactions:) @grouped_emoji_reactions = grouped_emoji_reactions end + def menu_id + ItemComponent::AddReactions.menu_id(journal) + end + + def reactable? + ItemComponent::AddReactions.new(journal:, grouped_emoji_reactions: {}).render? + end + private attr_reader :journal, :filter, :grouped_emoji_reactions diff --git a/app/controllers/work_packages/activities_tab_controller.rb b/app/controllers/work_packages/activities_tab_controller.rb index 982979319767..0be69de44e97 100644 --- a/app/controllers/work_packages/activities_tab_controller.rb +++ b/app/controllers/work_packages/activities_tab_controller.rb @@ -34,7 +34,7 @@ class WorkPackages::ActivitiesTabController < ApplicationController before_action :find_work_package before_action :find_project - before_action :find_journal, only: %i[item_actions edit cancel_edit update toggle_reaction] + before_action :find_journal, only: %i[emoji_actions item_actions edit cancel_edit update toggle_reaction] before_action :set_filter before_action :authorize @@ -86,6 +86,12 @@ def update_sorting respond_with_turbo_streams end + def emoji_actions + render WorkPackages::ActivitiesTab::Journals::ItemComponent::AddReactions + .new(journal: @journal, grouped_emoji_reactions: grouped_emoji_reactions_for_journal), + layout: false + end + def item_actions render WorkPackages::ActivitiesTab::Journals::ItemComponent::Actions.new(@journal), layout: false diff --git a/config/initializers/permissions.rb b/config/initializers/permissions.rb index 9c24b0d57c5a..041d7a4fda32 100644 --- a/config/initializers/permissions.rb +++ b/config/initializers/permissions.rb @@ -306,7 +306,7 @@ # FIXME: Although the endpoint is removed, the code checking whether a user # is eligible to add work packages through the API still seems to rely on this. journals: [:new], - "work_packages/activities_tab": %i[create toggle_reaction sanitize_internal_mentions] + "work_packages/activities_tab": %i[emoji_actions create toggle_reaction sanitize_internal_mentions] }, permissible_on: %i[work_package project], dependencies: :view_work_packages diff --git a/config/routes.rb b/config/routes.rb index c27328bce3f8..0afbdf9798dc 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -735,6 +735,7 @@ resources :activities, controller: "work_packages/activities_tab", only: %i[index create edit update] do member do get :cancel_edit + get :emoji_actions get :item_actions put :toggle_reaction end diff --git a/spec/support/components/work_packages/emoji_reactions.rb b/spec/support/components/work_packages/emoji_reactions.rb index 101db401ed19..6e19503aec20 100644 --- a/spec/support/components/work_packages/emoji_reactions.rb +++ b/spec/support/components/work_packages/emoji_reactions.rb @@ -92,11 +92,11 @@ def add_emoji_reaction_in_overlay(journal, emoji) end end - def open_emoji_reactions_overlay_for_journal(journal, &block) + def open_emoji_reactions_overlay_for_journal(journal, &) within_journal_entry(journal) do click_on "Add reaction" - wait_for { page }.to have_test_selector("emoji-reactions-overlay") - within_emoji_reactions_overlay(&block) + expect(page).to have_test_selector("emoji-reactions-overlay", wait: 10) + within_emoji_reactions_overlay(&) end end