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:
Rajat Talesra 2023-06-28 12:35:15 +05:30 committed by GitHub
parent ce902fe1f8
commit 28b8980c76
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 154 additions and 2 deletions

View file

@ -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);

View file

@ -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

View file

@ -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

View file

@ -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? %>

View 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 %>

View file

@ -39,5 +39,6 @@ en:
other: "%{count} members"
support: Support email
team: Meet the team
all_members: See All Members
twitter:
icon: Twitter logo

View file

@ -39,5 +39,6 @@ fr:
other: "%{count} members"
support: Support email
team: Meet the team
all_members: See All Members
twitter:
icon: Twitter logo

View file

@ -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"

View file

@ -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