From 28b8980c76d706198f5df8492e884fda9b8cd9ec Mon Sep 17 00:00:00 2001 From: Rajat Talesra Date: Wed, 28 Jun 2023 12:35:15 +0530 Subject: [PATCH] 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 --- app/assets/stylesheets/widgets.scss | 56 +++++++++++++++++++ app/controllers/organizations_controller.rb | 6 ++ app/controllers/stories_controller.rb | 5 ++ app/views/organizations/_sidebar.html.erb | 7 ++- app/views/organizations/members.html.erb | 29 ++++++++++ config/locales/views/organizations/en.yml | 1 + config/locales/views/organizations/fr.yml | 1 + config/routes.rb | 1 + .../user_views_an_organization_spec.rb | 50 ++++++++++++++++- 9 files changed, 154 insertions(+), 2 deletions(-) create mode 100644 app/views/organizations/members.html.erb diff --git a/app/assets/stylesheets/widgets.scss b/app/assets/stylesheets/widgets.scss index d64fe5314..d02e98eb3 100644 --- a/app/assets/stylesheets/widgets.scss +++ b/app/assets/stylesheets/widgets.scss @@ -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); diff --git a/app/controllers/organizations_controller.rb b/app/controllers/organizations_controller.rb index 590e1f2a0..ccfcee31e 100644 --- a/app/controllers/organizations_controller.rb +++ b/app/controllers/organizations_controller.rb @@ -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 diff --git a/app/controllers/stories_controller.rb b/app/controllers/stories_controller.rb index 1df0d6244..6386fa87c 100644 --- a/app/controllers/stories_controller.rb +++ b/app/controllers/stories_controller.rb @@ -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 diff --git a/app/views/organizations/_sidebar.html.erb b/app/views/organizations/_sidebar.html.erb index 9bce1237a..31ca12ba9 100644 --- a/app/views/organizations/_sidebar.html.erb +++ b/app/views/organizations/_sidebar.html.erb @@ -10,7 +10,7 @@
- <% @organization_users.find_each_respecting_scope do |user| %> + <% @organization_users.limit(@user_limit).find_each_respecting_scope do |user| %> <% end %>
+ <% if @organization_users.count > @user_limit %> + + <%= t("views.organizations.all_members") %> + + <% end %> <% end %> <% if @organization.story.present? %> diff --git a/app/views/organizations/members.html.erb b/app/views/organizations/members.html.erb new file mode 100644 index 000000000..3d41b5276 --- /dev/null +++ b/app/views/organizations/members.html.erb @@ -0,0 +1,29 @@ +<% title @organization.name %> +
+
+

<%= @organization.name %> (<%= @members.count %>)

+
+ <% @members.each_with_index do |member, index| %> +
+
+
+ + <%= member.username %> profile image + +
+ +
+ +
+ <% end %> +
+
+ +<%= javascript_packs_with_chunks_tag "followButtons", defer: true %> diff --git a/config/locales/views/organizations/en.yml b/config/locales/views/organizations/en.yml index 0fd130edb..0859a3b1f 100644 --- a/config/locales/views/organizations/en.yml +++ b/config/locales/views/organizations/en.yml @@ -39,5 +39,6 @@ en: other: "%{count} members" support: Support email team: Meet the team + all_members: See All Members twitter: icon: Twitter logo diff --git a/config/locales/views/organizations/fr.yml b/config/locales/views/organizations/fr.yml index 2cbad6f30..dc471871c 100644 --- a/config/locales/views/organizations/fr.yml +++ b/config/locales/views/organizations/fr.yml @@ -39,5 +39,6 @@ fr: other: "%{count} members" support: Support email team: Meet the team + all_members: See All Members twitter: icon: Twitter logo diff --git a/config/routes.rb b/config/routes.rb index 8682e08d8..dee4a665d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -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" diff --git a/spec/system/organization/user_views_an_organization_spec.rb b/spec/system/organization/user_views_an_organization_spec.rb index fa5302f06..e5fb95779 100644 --- a/spec/system/organization/user_views_an_organization_spec.rb +++ b/spec/system/organization/user_views_an_organization_spec.rb @@ -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