Skip to content

Commit ed95633

Browse files
authored
Merge pull request #3765 from AlchemyCMS/admin-user-name-component
feat: Extract admin user name display into component
2 parents a17d690 + 4b78017 commit ed95633

6 files changed

Lines changed: 103 additions & 20 deletions

File tree

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
module Alchemy
2+
module Admin
3+
# This component is used to display the name of the current Alchemy user in the admin interface.
4+
class CurrentUserName < ViewComponent::Base
5+
def initialize(user:)
6+
@user = user
7+
@display_name = user.try(:alchemy_display_name)
8+
end
9+
10+
def call
11+
tag.span class: "current-user-name" do
12+
safe_join [
13+
'<alchemy-icon name="user" size="1x"></alchemy-icon>'.html_safe,
14+
link_to_if(edit_user_path, display_name, edit_user_path)
15+
]
16+
end
17+
end
18+
19+
def render?
20+
user && display_name.present?
21+
end
22+
23+
private
24+
25+
attr_reader :user, :display_name
26+
27+
def edit_user_path
28+
return unless Alchemy.config.edit_user_path
29+
30+
Alchemy.config.edit_user_path.gsub(":id", user.id.to_s)
31+
end
32+
end
33+
end
34+
end

app/helpers/alchemy/admin/base_helper.rb

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,12 @@ module BaseHelper
1717
#
1818
# In order to represent your own +User+'s class instance,
1919
# you should add a +alchemy_display_name+ method to your +User+ class
20-
#
20+
# @deprecated Use the +CurrentAlchemyUserName+ component instead.
2121
def current_alchemy_user_name
22-
name = current_alchemy_user.try(:alchemy_display_name)
23-
if name.present?
24-
content_tag :span, class: "current-user-name" do
25-
"#{render_icon(:user, size: "1x")} #{name}".html_safe
26-
end
27-
end
22+
render Alchemy::Admin::CurrentUserName.new(user: current_alchemy_user)
2823
end
24+
deprecate current_alchemy_user_name: "Use the Alchemy::Admin::CurrentUserName component instead.",
25+
deprecator: Alchemy::Deprecation
2926

3027
# This helper renders the link to an dialog.
3128
#
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<div id="user_info">
2-
<%= current_alchemy_user_name %>
2+
<%= render Alchemy::Admin::CurrentUserName.new(user: current_alchemy_user) %>
33
<%= render Alchemy::Admin::TimezoneSelect.new %>
44
<%= render Alchemy::Admin::LocaleSelect.new %>
55
</div>

lib/alchemy/configurations/main.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,18 @@ def user_class_name = "::#{raw_user_class}"
434434
# The path to the page showing the user they're unauthorized
435435
option :unauthorized_path, :string, default: "/"
436436

437+
# === Edit User Path
438+
#
439+
# The path to the edit user form.
440+
#
441+
# == Example
442+
#
443+
# "/admin/users/:id/edit"
444+
#
445+
# NOTE: The :id placeholder will be replaced with the current_alchemy_user's id.
446+
#
447+
option :edit_user_path, :string
448+
437449
# === CanCan abilities
438450
#
439451
# If your app or your engine has own CanCan abilities you must register them.
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
require "rails_helper"
2+
3+
RSpec.describe Alchemy::Admin::CurrentUserName, type: :component do
4+
subject(:render) do
5+
render_inline described_class.new(user:)
6+
rendered_content
7+
end
8+
9+
context "with no user" do
10+
let(:user) { nil }
11+
12+
it { expect(render).to be_blank }
13+
end
14+
15+
context "with a user" do
16+
context "having a `alchemy_display_name` method" do
17+
let(:user) { double("User", alchemy_display_name: "Peter Schroeder") }
18+
19+
it "Returns a span showing the name of the currently logged in user." do
20+
render
21+
expect(page).to have_content("Peter Schroeder")
22+
expect(page).to have_selector("span.current-user-name")
23+
end
24+
end
25+
26+
context "not having a `alchemy_display_name` method" do
27+
let(:user) { double("User", name: "Peter Schroeder") }
28+
29+
it { expect(render).to be_blank }
30+
end
31+
32+
context "with an edit_user_path configured" do
33+
before do
34+
stub_alchemy_config(edit_user_path: "/users/:id/edit")
35+
render
36+
end
37+
38+
let(:user) { double("User", id: 42, alchemy_display_name: "Peter Schroeder") }
39+
40+
it "links the user name to the edit user path" do
41+
expect(page).to have_link("Peter Schroeder", href: "/users/42/edit")
42+
end
43+
end
44+
end
45+
end

spec/helpers/alchemy/admin/base_helper_spec.rb

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -178,21 +178,16 @@ module Alchemy
178178
describe "#current_alchemy_user_name" do
179179
subject { helper.current_alchemy_user_name }
180180

181-
before { expect(helper).to receive(:current_alchemy_user).and_return(user) }
181+
let(:user) { double("User", alchemy_display_name: "Peter Schroeder") }
182182

183-
context "with a user having a `alchemy_display_name` method" do
184-
let(:user) { double("User", alchemy_display_name: "Peter Schroeder") }
185-
186-
it "Returns a span showing the name of the currently logged in user." do
187-
is_expected.to have_content("Peter Schroeder")
188-
is_expected.to have_selector("span.current-user-name")
189-
end
183+
before do
184+
expect(helper).to receive(:current_alchemy_user).and_return(user)
185+
allow(helper).to receive(:render).with(instance_of(Alchemy::Admin::CurrentUserName))
190186
end
191187

192-
context "with a user not having a `alchemy_display_name` method" do
193-
let(:user) { double("User", name: "Peter Schroeder") }
194-
195-
it { is_expected.to be_nil }
188+
it "renders the Alchemy::Admin::CurrentUserName component", :silence_deprecations do
189+
subject
190+
expect(helper).to have_received(:render).with(instance_of(Alchemy::Admin::CurrentUserName))
196191
end
197192
end
198193

0 commit comments

Comments
 (0)