-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This migrates the `users/:id/edit` page to the new admin. It still relies on the old backend admin controller for the `#update` action as well as the other top level user tabs such as address, order history, and so on. Co-authored-by: benjamin wil <[email protected]>
- Loading branch information
1 parent
7b4addf
commit 25a87fc
Showing
13 changed files
with
350 additions
and
4 deletions.
There are no files selected for viewing
49 changes: 49 additions & 0 deletions
49
admin/app/components/solidus_admin/users/edit/api_access/component.html.erb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
<%= render component('ui/panel').new(title: t('.api_access')) do %> | ||
<section> | ||
<% if @user.spree_api_key.present? %> | ||
<div id="current-api-key"> | ||
<h2 class="py-1.5 font-semibold"><%= t('.key') %></h2> | ||
<% if @user == helpers.current_solidus_admin_user %> | ||
<%= @user.spree_api_key %> | ||
<% else %> | ||
<i>(<%= t('spree.hidden') %>)</i> | ||
<% end %> | ||
</div> | ||
|
||
<div class="py-1.5 text-center"> | ||
<%= form_with url: spree.admin_user_api_key_path(@user), method: :delete, local: true, html: { class: 'clear_api_key inline-flex' } do %> | ||
<%= render component("ui/button").new( | ||
text: t('.clear_key'), | ||
scheme: :secondary, | ||
type: :submit, | ||
"data-action": "click->#{stimulus_id}#confirm", | ||
"data-#{stimulus_id}-message-param": t(".confirm_clear_key"), | ||
) %> | ||
<% end %> | ||
|
||
<%= form_with url: spree.admin_user_api_key_path(@user), method: :post, local: true, html: { class: 'regen_api_key inline-flex' } do %> | ||
<%= render component("ui/button").new( | ||
text: t('.regenerate_key'), | ||
scheme: :secondary, | ||
type: :submit, | ||
"data-action": "click->#{stimulus_id}#confirm", | ||
"data-#{stimulus_id}-message-param": t(".confirm_regenerate_key"), | ||
) %> | ||
<% end %> | ||
</div> | ||
|
||
<% else %> | ||
<div class="no-objects-found"><%= t('.no_key') %></div> | ||
<div class="filter-actions actions"> | ||
<div class="py-1.5 text-center"> | ||
<%= form_with url: spree.admin_user_api_key_path(@user), method: :post, local: true, html: { class: 'generate_api_key inline-flex' } do %> | ||
<%= render component("ui/button").new( | ||
text: t('.generate_key'), | ||
type: :submit, | ||
) %> | ||
<% end %> | ||
</div> | ||
</div> | ||
<% end %> | ||
</section> | ||
<% end %> |
9 changes: 9 additions & 0 deletions
9
admin/app/components/solidus_admin/users/edit/api_access/component.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { Controller } from "@hotwired/stimulus" | ||
|
||
export default class extends Controller { | ||
confirm(event) { | ||
if (!confirm(event.params.message)) { | ||
event.preventDefault() | ||
} | ||
} | ||
} |
7 changes: 7 additions & 0 deletions
7
admin/app/components/solidus_admin/users/edit/api_access/component.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# frozen_string_literal: true | ||
|
||
class SolidusAdmin::Users::Edit::ApiAccess::Component < SolidusAdmin::BaseComponent | ||
def initialize(user:) | ||
@user = user | ||
end | ||
end |
10 changes: 10 additions & 0 deletions
10
admin/app/components/solidus_admin/users/edit/api_access/component.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
en: | ||
api_access: API Access | ||
no_key: No key | ||
key: "Key" | ||
generate_key: Generate API key | ||
clear_key: Clear key | ||
regenerate_key: Regenerate key | ||
hidden: Hidden | ||
confirm_clear_key: Are you sure you want to clear this user's API key? It will invalidate the existing key. | ||
confirm_regenerate_key: Are you sure you want to regenerate this user's API key? It will invalidate the existing key. |
62 changes: 62 additions & 0 deletions
62
admin/app/components/solidus_admin/users/edit/component.html.erb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
<%= page do %> | ||
<%= page_header do %> | ||
<%= page_header_back(solidus_admin.users_path) %> | ||
<%= page_header_title(t(".title", email: @user.email)) %> | ||
|
||
<% # @todo: I am not sure how we want to handle Cancan stuff in the new admin. %> | ||
<% # if can?(:admin, Spree::Order) && can?(:create, Spree::Order) %> | ||
<%= page_header_actions do %> | ||
<%= render component("ui/button").new(tag: :a, text: t(".create_order_for_user"), href: spree.new_admin_order_path(user_id: @user.id)) %> | ||
<% end %> | ||
<% # end %> | ||
<% end %> | ||
|
||
<%= page_header do %> | ||
<% tabs.each do |tab| %> | ||
<%= render(component("ui/button").new(tag: :a, scheme: :ghost, text: tab[:text], 'aria-current': tab[:current], href: tab[:href])) %> | ||
<% end %> | ||
<% end %> | ||
|
||
<%= page_with_sidebar do %> | ||
<%= page_with_sidebar_main do %> | ||
|
||
<%= render component('ui/panel').new(title: Spree.user_class.model_name.human) do %> | ||
<%= form_for @user, url: solidus_admin.user_path(@user), html: { id: form_id } do |f| %> | ||
<div class="py-1.5"> | ||
<%= render component("ui/forms/field").text_field(f, :email, autocomplete: "none") %> | ||
</div> | ||
<div class="py-1.5"> | ||
<%= render component("ui/forms/field").text_field(f, :password, autocomplete: "none") %> | ||
</div> | ||
<div class="py-1.5"> | ||
<%= render component("ui/forms/field").text_field(f, :password_confirmation) %> | ||
</div> | ||
<div class="py-1.5"> | ||
<%= render component("ui/checkbox_row").new(options: role_options, row_title: "Roles", form: f, method: "spree_role_ids", layout: :subsection) %> | ||
</div> | ||
<div class="py-1.5 text-center"> | ||
<%= render component("ui/button").new(tag: :button, text: t(".update"), form: form_id) %> | ||
<%= render component("ui/button").new(tag: :a, text: t(".cancel"), href: solidus_admin.user_path(@user), scheme: :secondary) %> | ||
</div> | ||
<% end %> | ||
<% end %> | ||
<%= render component("users/edit/api_access").new(user: @user) %> | ||
<% end %> | ||
<%= page_with_sidebar_aside do %> | ||
<%= render component("ui/panel").new(title: t("spree.lifetime_stats")) do %> | ||
<%= render component("ui/details_list").new( | ||
items: [ | ||
{ label: t("spree.total_sales"), value: @user.display_lifetime_value.to_html }, | ||
{ label: t("spree.order_count"), value: @user.order_count.to_i }, | ||
{ label: t("spree.average_order_value"), value: @user.display_average_order_value.to_html }, | ||
{ label: t("spree.member_since"), value: @user.created_at.to_date }, | ||
{ label: t(".last_active"), value: last_login(@user) }, | ||
] | ||
) %> | ||
<% end %> | ||
<% end %> | ||
<% end %> | ||
<% end %> |
63 changes: 63 additions & 0 deletions
63
admin/app/components/solidus_admin/users/edit/component.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
# frozen_string_literal: true | ||
|
||
class SolidusAdmin::Users::Edit::Component < SolidusAdmin::BaseComponent | ||
include SolidusAdmin::Layout::PageHelpers | ||
|
||
def initialize(user:) | ||
@user = user | ||
end | ||
|
||
def form_id | ||
@form_id ||= "#{stimulus_id}--form-#{@user.id}" | ||
end | ||
|
||
def tabs | ||
[ | ||
{ | ||
text: t('.account'), | ||
href: solidus_admin.users_path, | ||
current: action_name == "show", | ||
}, | ||
{ | ||
text: t('.addresses'), | ||
href: spree.addresses_admin_user_path(@user), | ||
# @todo: update this "current" logic once folded into new admin | ||
current: action_name != "show", | ||
}, | ||
{ | ||
text: t('.order_history'), | ||
href: spree.orders_admin_user_path(@user), | ||
# @todo: update this "current" logic once folded into new admin | ||
current: action_name != "show", | ||
}, | ||
{ | ||
text: t('.items'), | ||
href: spree.items_admin_user_path(@user), | ||
# @todo: update this "current" logic once folded into new admin | ||
current: action_name != "show", | ||
}, | ||
{ | ||
text: t('.store_credit'), | ||
href: spree.admin_user_store_credits_path(@user), | ||
# @todo: update this "current" logic once folded into new admin | ||
current: action_name != "show", | ||
}, | ||
] | ||
end | ||
|
||
def last_login(user) | ||
return t('.last_login.never') if user.try(:last_sign_in_at).blank? | ||
|
||
t( | ||
'.last_login.login_time_ago', | ||
# @note The second `.try` is only here for the specs to work. | ||
last_login_time: time_ago_in_words(user.try(:last_sign_in_at)) | ||
).capitalize | ||
end | ||
|
||
def role_options | ||
Spree::Role.all.map do |role| | ||
{ label: role.name, id: role.id } | ||
end | ||
end | ||
end |
16 changes: 16 additions & 0 deletions
16
admin/app/components/solidus_admin/users/edit/component.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
en: | ||
title: "Users / %{email}" | ||
account: Account | ||
addresses: Addresses | ||
order_history: Order History | ||
items: Items | ||
store_credit: Store Credit | ||
last_active: Last Active | ||
last_login: | ||
login_time_ago: "%{last_login_time} ago" | ||
never: Never | ||
invitation_sent: Invitation sent | ||
create_order_for_user: Create order for this user | ||
update: Update | ||
cancel: Cancel | ||
back: Back |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,7 +3,11 @@ | |
require "spec_helper" | ||
|
||
describe "Users", :js, type: :feature do | ||
before { sign_in create(:admin_user, email: "[email protected]") } | ||
let(:admin) { create(:admin_user, email: "[email protected]") } | ||
|
||
before do | ||
sign_in admin | ||
end | ||
|
||
it "lists users and allows deleting them" do | ||
create(:user, email: "[email protected]") | ||
|
@@ -52,4 +56,57 @@ | |
expect(page).not_to have_content("Never") | ||
end | ||
end | ||
|
||
context "when editing an existing user" do | ||
before do | ||
# This is needed for the actions which are still powered by the backend | ||
# and not the new admin. (#update, etc.) | ||
stub_authorization!(admin) | ||
|
||
create(:user, email: "[email protected]") | ||
visit "/admin/users" | ||
find_row("[email protected]").click | ||
end | ||
|
||
it "shows the edit page" do | ||
expect(page).to have_content("Users / [email protected]") | ||
expect(page).to have_content("Lifetime Stats") | ||
expect(page).to have_content("Roles") | ||
expect(find("label", text: /admin/i).find("input[type=checkbox]").checked?).to eq(false) | ||
end | ||
|
||
it "allows editing of the existing user" do | ||
# API key interactions | ||
expect(page).to have_content("No key") | ||
click_on "Generate API key" | ||
expect(page).to have_content("Key generated") | ||
expect(page).to have_content("(hidden)") | ||
|
||
click_on "Regenerate key" | ||
expect(page).to have_content("Key generated") | ||
expect(page).to have_content("(hidden)") | ||
|
||
click_on "Clear key" | ||
expect(page).to have_content("Key cleared") | ||
expect(page).to have_content("No key") | ||
|
||
# Update user | ||
within("form.edit_user") do | ||
fill_in "Email", with: "[email protected]" | ||
find("label", text: /admin/i).find("input[type=checkbox]").check | ||
click_on "Update" | ||
end | ||
|
||
expect(page).to have_content("Users / [email protected]") | ||
expect(find("label", text: /admin/i).find("input[type=checkbox]").checked?).to eq(true) | ||
|
||
# Cancel out of editing | ||
within("form.edit_user") do | ||
fill_in "Email", with: "[email protected]" | ||
click_on "Cancel" | ||
end | ||
|
||
expect(page).not_to have_content("[email protected]") | ||
end | ||
end | ||
end |
Oops, something went wrong.