Skip to content

Commit c31d5e5

Browse files
committed
[DREAM-697] Migrate notifications list
Uses the shared list for project-specific notification settings. https://community.openproject.org/wp/DREAM-697
1 parent 60e34e5 commit c31d5e5

2 files changed

Lines changed: 111 additions & 37 deletions

File tree

app/components/my/notifications/show_page_component.html.erb

Lines changed: 29 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -82,43 +82,35 @@ See COPYRIGHT and LICENSE files for more details.
8282
component.with_description { t("my_account.notifications.project_specific_settings.description") }
8383
end %>
8484

85-
<% if project_notification_settings.any? %>
86-
<%= render(Primer::Beta::BorderBox.new(mb: 3)) do |box| %>
87-
<% box.with_header { t("my_account.notifications.project_specific_settings.list_header") } %>
88-
<% project_notification_settings.each do |setting| %>
89-
<% box.with_row(test_selector: "project-specific-settings-list") do %>
90-
<%= flex_layout(justify_content: :space_between, align_items: :center, width: :full) do |flex| %>
91-
<%= flex.with_column do %>
92-
<span><%= setting.project.name %></span>
93-
<% end %>
94-
<%= flex.with_column do %>
95-
<%= render(Primer::Alpha::ActionMenu.new(test_selector: "project-specific-settings-list--action-menu")) do |menu|
96-
menu.with_show_button(
97-
scheme: :invisible,
98-
size: :small,
99-
icon: :"kebab-horizontal",
100-
"aria-label": t(:label_open_menu),
101-
tooltip_direction: :w
102-
)
103-
menu.with_item(
104-
label: t("button_edit"),
105-
href: edit_project_settings_url(setting.project_id),
106-
content_arguments: { data: { controller: "async-dialog" } }
107-
) do |item|
108-
item.with_leading_visual_icon(icon: :pencil)
109-
end
110-
menu.with_item(
111-
label: t("button_delete"),
112-
scheme: :danger,
113-
href: project_setting_url(setting.project_id),
114-
content_arguments: { data: { turbo_method: :delete, turbo_confirm: t("text_are_you_sure") } }
115-
) do |item|
116-
item.with_leading_visual_icon(icon: :trash)
117-
end
118-
end %>
119-
<% end %>
120-
<% end %>
121-
<% end %>
85+
<%= render(OpenProject::Common::BorderBoxListComponent.new(container: "project-specific-notification-settings", mb: 3)) do |list| %>
86+
<% list.with_header(title: t("my_account.notifications.project_specific_settings.list_header")) %>
87+
<% project_notification_settings.each do |setting| %>
88+
<% list.with_item(test_selector: "project-specific-settings-list") do |item| %>
89+
<% item.with_menu(
90+
test_selector: "project-specific-settings-list--action-menu",
91+
button_arguments: {
92+
size: :small,
93+
aria: { label: t(:label_open_menu) },
94+
tooltip_direction: :w
95+
}
96+
) do |menu|
97+
menu.with_item(
98+
label: t("button_edit"),
99+
href: edit_project_settings_url(setting.project_id),
100+
content_arguments: { data: { controller: "async-dialog" } }
101+
) do |menu_item|
102+
menu_item.with_leading_visual_icon(icon: :pencil)
103+
end
104+
menu.with_item(
105+
label: t("button_delete"),
106+
scheme: :danger,
107+
href: project_setting_url(setting.project_id),
108+
content_arguments: { data: { turbo_method: :delete, turbo_confirm: t("text_are_you_sure") } }
109+
) do |menu_item|
110+
menu_item.with_leading_visual_icon(icon: :trash)
111+
end
112+
end %>
113+
<span><%= setting.project.name %></span>
122114
<% end %>
123115
<% end %>
124116
<% end %>
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# frozen_string_literal: true
2+
3+
#-- copyright
4+
# OpenProject is an open source project management software.
5+
# Copyright (C) the OpenProject GmbH
6+
#
7+
# This program is free software; you can redistribute it and/or
8+
# modify it under the terms of the GNU General Public License version 3.
9+
#
10+
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
11+
# Copyright (C) 2006-2013 Jean-Philippe Lang
12+
# Copyright (C) 2010-2013 the ChiliProject Team
13+
#
14+
# This program is free software; you can redistribute it and/or
15+
# modify it under the terms of the GNU General Public License
16+
# as published by the Free Software Foundation; either version 2
17+
# of the License, or (at your option) any later version.
18+
#
19+
# This program is distributed in the hope that it will be useful,
20+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
21+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22+
# GNU General Public License for more details.
23+
#
24+
# You should have received a copy of the GNU General Public License
25+
# along with this program; if not, write to the Free Software
26+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
27+
#
28+
# See COPYRIGHT and LICENSE files for more details.
29+
#++
30+
31+
require "rails_helper"
32+
33+
RSpec.describe My::Notifications::ShowPageComponent, type: :component do
34+
let(:user) { create(:user) }
35+
# create(:user) already seeds the global (project-less) notification setting.
36+
let(:global_setting) { user.notification_settings.find_by!(project: nil) }
37+
38+
subject(:rendered_component) do
39+
with_request_url("/my/notifications") do
40+
render_inline(
41+
described_class.new(
42+
user:,
43+
global_notification_setting: global_setting,
44+
update_participating_url: { action: "update_participating" },
45+
update_non_participating_url: { action: "update_non_participating" },
46+
update_date_alerts_url: { action: "update_date_alerts" },
47+
new_project_settings_url: "/my/project_notifications/new",
48+
edit_project_settings_url: ->(project_id) { "/my/project_notifications/#{project_id}/edit" },
49+
project_setting_url: ->(project_id) { "/my/project_notifications/#{project_id}" }
50+
)
51+
)
52+
end
53+
end
54+
55+
context "with project-specific settings" do
56+
let(:project) { create(:project) }
57+
let!(:project_setting) { create(:notification_setting, user:, project:) }
58+
59+
it "renders the list header and the add-project action", :aggregate_failures do
60+
expect(rendered_component).to have_css(".Box-header") do |header|
61+
expect(header).to have_heading(I18n.t("my_account.notifications.project_specific_settings.list_header"))
62+
end
63+
expect(rendered_component).to have_link(
64+
I18n.t("my_account.notifications.project_specific_settings.add_button"),
65+
href: "/my/project_notifications/new"
66+
)
67+
end
68+
69+
it "renders a row per project-specific setting with an edit/delete actions menu", :aggregate_failures do
70+
expect(rendered_component).to have_css(".Box-row", text: project.name) do |row|
71+
expect(row).to have_button(accessible_name: I18n.t(:label_open_menu))
72+
expect(row).to have_link(I18n.t(:button_edit), href: "/my/project_notifications/#{project.id}/edit")
73+
expect(row).to have_link(I18n.t(:button_delete), href: "/my/project_notifications/#{project.id}")
74+
end
75+
end
76+
end
77+
78+
context "without project-specific settings" do
79+
it_behaves_like "rendering Blank Slate",
80+
heading: I18n.t(:label_nothing_display)
81+
end
82+
end

0 commit comments

Comments
 (0)