Organisation members page to show all users (#19611)
* Basic implementations * Working implementation * See all button added * Added tests for See All Members button * Added click test * Grid design * Nit fix to trigger build failure * Applied design changes * Nit design fixes * Revert limit * Applied Ben's suggestion * Removed fixed hight * Grid layout changes * Updated test * Indentation fix * Added members page test
This commit is contained in:
parent
ce902fe1f8
commit
28b8980c76
9 changed files with 154 additions and 2 deletions
|
|
@ -303,12 +303,68 @@
|
|||
}
|
||||
}
|
||||
a {
|
||||
width: calc(100% - 40px);
|
||||
justify-content: center;
|
||||
&:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.org-member-page {
|
||||
.member-item {
|
||||
width: 100%;
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 12px;
|
||||
|
||||
.member-item-top {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
|
||||
.member-user-pic {
|
||||
img {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
aspect-ratio: 1/1;
|
||||
margin: 3px;
|
||||
border-radius: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.member-item-bottom {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 1px;
|
||||
flex-grow: 0;
|
||||
|
||||
.truncate {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.member-username {
|
||||
font-weight: var(--fw-normal);
|
||||
font-size: var(--fs-s);
|
||||
line-height: var(--lh-base);
|
||||
letter-spacing: -0.02em;
|
||||
color: var(--color-secondary);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.crayons-sponsorship {
|
||||
padding: var(--su-3);
|
||||
padding-bottom: var(--su-4);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
class OrganizationsController < ApplicationController
|
||||
after_action :verify_authorized
|
||||
skip_after_action :verify_authorized, only: :members
|
||||
|
||||
ORGANIZATIONS_PERMITTED_PARAMS = %i[
|
||||
id
|
||||
|
|
@ -93,6 +94,11 @@ class OrganizationsController < ApplicationController
|
|||
redirect_to user_settings_path(:organization)
|
||||
end
|
||||
|
||||
def members
|
||||
@organization = Organization.find_by(slug: params[:slug])
|
||||
@members = @organization.users
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def permitted_params
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ class StoriesController < ApplicationController
|
|||
|
||||
before_action :authenticate_user!, except: %i[index show]
|
||||
before_action :set_cache_control_headers, only: %i[index show]
|
||||
before_action :set_user_limit, only: %i[index show]
|
||||
before_action :redirect_to_lowercase_username, only: %i[index]
|
||||
|
||||
rescue_from ArgumentError, with: :bad_request
|
||||
|
|
@ -48,6 +49,10 @@ class StoriesController < ApplicationController
|
|||
|
||||
private
|
||||
|
||||
def set_user_limit
|
||||
@user_limit = 50
|
||||
end
|
||||
|
||||
def assign_hero_banner
|
||||
@hero_display_ad = DisplayAd.for_display(area: "home_hero", user_signed_in: user_signed_in?)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
</h3>
|
||||
</header>
|
||||
<div class="org-sidebar-widget-body">
|
||||
<% @organization_users.find_each_respecting_scope do |user| %>
|
||||
<% @organization_users.limit(@user_limit).find_each_respecting_scope do |user| %>
|
||||
<div class="org-sidebar-widget-user-pic">
|
||||
<a href="/<%= user.username %>">
|
||||
<img src="<%= user.profile_image_url_for(length: 90) %>" alt="<%= user.username %> profile image" loading="lazy" />
|
||||
|
|
@ -18,6 +18,11 @@
|
|||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% if @organization_users.count > @user_limit %>
|
||||
<a class="c-cta ml-5 mt-1 mr-5 mb-5" onclick="location.href='/<%= @organization.slug %>/members'">
|
||||
<%= t("views.organizations.all_members") %>
|
||||
</a>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% if @organization.story.present? %>
|
||||
|
|
|
|||
29
app/views/organizations/members.html.erb
Normal file
29
app/views/organizations/members.html.erb
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
<% title @organization.name %>
|
||||
<div class="blank-space"></div>
|
||||
<main class="org-member-page crayons-layout px-4 m:px-9 gap-0">
|
||||
<h1 class="crayons-title"><%= @organization.name %> (<%= @members.count %>)</h1>
|
||||
<div class="mt-4 l:mt-7 grid gap-4 grid-cols-1 s:grid-cols-1 m:grid-cols-2 l:grid-cols-3 xl:grid-cols-4 mb-6">
|
||||
<% @members.each_with_index do |member, index| %>
|
||||
<div class="crayons-card member-item">
|
||||
<div class="member-item-top">
|
||||
<div class="member-user-pic">
|
||||
<a href="/<%= member.username %>">
|
||||
<img src="<%= member.profile_image_url_for(length: 90) %>" alt="<%= member.username %> profile image" loading="lazy" />
|
||||
</a>
|
||||
</div>
|
||||
<button id="user-follow-butt-<%= member.username %>" class="crayons-btn whitespace-nowrap follow-action-button follow-user" data-info='<%= DataInfo.to_json(object: member) %>'><%= t("views.users.follow") %></button>
|
||||
</div>
|
||||
<div class="member-item-bottom">
|
||||
<a class="crayons-subtitle-3 truncate" href="/<%= member.username %>">
|
||||
<%= member.name %>
|
||||
</a>
|
||||
<a class="member-username truncate" href="/<%= member.username %>">
|
||||
@<%= member.username %>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<%= javascript_packs_with_chunks_tag "followButtons", defer: true %>
|
||||
|
|
@ -39,5 +39,6 @@ en:
|
|||
other: "%{count} members"
|
||||
support: Support email
|
||||
team: Meet the team
|
||||
all_members: See All Members
|
||||
twitter:
|
||||
icon: Twitter logo
|
||||
|
|
|
|||
|
|
@ -39,5 +39,6 @@ fr:
|
|||
other: "%{count} members"
|
||||
support: Support email
|
||||
team: Meet the team
|
||||
all_members: See All Members
|
||||
twitter:
|
||||
icon: Twitter logo
|
||||
|
|
|
|||
|
|
@ -235,6 +235,7 @@ Rails.application.routes.draw do
|
|||
get "/💸", to: redirect("t/hiring")
|
||||
get "/survey", to: redirect("https://dev.to/ben/final-thoughts-on-the-state-of-the-web-survey-44nn")
|
||||
get "/search", to: "stories/articles_search#index"
|
||||
get "/:slug/members", to: "organizations#members", as: :organization_members
|
||||
post "articles/preview", to: "articles#preview"
|
||||
post "comments/preview", to: "comments#preview"
|
||||
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ RSpec.describe "Organization index" do
|
|||
end
|
||||
end
|
||||
|
||||
context "when there are multiple members in the organization" do
|
||||
context "when there are multiple members in the organization within a limit" do
|
||||
let(:many_members_org) { create(:organization) }
|
||||
|
||||
let(:some_badges_member) { create(:user, badge_achievements_count: 15) }
|
||||
|
|
@ -101,5 +101,53 @@ RSpec.describe "Organization index" do
|
|||
expect(page.find(nth_avatar(4))).to have_link(nil, href: no_badges_member.path)
|
||||
end
|
||||
end
|
||||
|
||||
it "does not show the 'See all members' link" do
|
||||
within("#sidebar-left") do
|
||||
expect(page).not_to have_content("See All Members")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when there are more than 50 members in the organization" do
|
||||
let(:many_members_org) { create(:organization) }
|
||||
|
||||
before do
|
||||
55.times do
|
||||
user = create(:user, badge_achievements_count: rand(1..100))
|
||||
create(:organization_membership, user: user, organization: many_members_org)
|
||||
end
|
||||
visit "/#{many_members_org.slug}"
|
||||
end
|
||||
|
||||
def nth_avatar(user_position)
|
||||
".org-sidebar-widget-user-pic:nth-child(#{user_position})"
|
||||
end
|
||||
|
||||
it "shows the sidebar till 50th user only" do
|
||||
within("#sidebar-left") do
|
||||
expect(page).to have_content("Meet the team")
|
||||
|
||||
# This checks that first 50 users are available and 51st item is not.
|
||||
(1..50).each do |i|
|
||||
expect(page).to have_css(nth_avatar(i))
|
||||
end
|
||||
|
||||
expect(page).not_to have_css(nth_avatar(51))
|
||||
end
|
||||
end
|
||||
|
||||
it "shows the 'See All Members' link" do
|
||||
within(".org-sidebar-widget") do
|
||||
expect(page).to have_content("See All Members")
|
||||
end
|
||||
end
|
||||
|
||||
it "displays the members on the '/members' page" do
|
||||
visit "/#{many_members_org.slug}/members"
|
||||
within(".grid-cols-1") do
|
||||
expect(page).to have_selector(".member-item", count: 55)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue