From 692acd3cb2c1e845cea3922feffd3f038c7ed162 Mon Sep 17 00:00:00 2001 From: Jacob Herrington Date: Wed, 9 Dec 2020 09:41:11 -0600 Subject: [PATCH] Render Profile Fields on user profiles (#11485) * Render left sidebar attributes on profile * Display header profile fields * Make changes to protect DEV data * Don't render DEV header fields twice * Wrap profile UI changes in a FeatureFlag * Add spec to test mulitple display areas * Use select over reject Co-authored-by: Michael Kohl * Move comment for documentation generators * Update dev profile fields csv data Co-authored-by: Michael Kohl Co-authored-by: Ben Halpern --- app/controllers/stories_controller.rb | 1 + app/decorators/profile_decorator.rb | 14 +++ app/models/profile.rb | 1 + app/views/users/_metadata.html.erb | 106 ++++++++++++++------ app/views/users/_profile_fields.html.erb | 0 app/views/users/_sidebar.html.erb | 88 +++++++++------- db/seeds.rb | 1 - lib/data/dev_profile_fields.csv | 26 ++--- spec/system/user/user_edits_profile_spec.rb | 54 ++++++++++ 9 files changed, 210 insertions(+), 81 deletions(-) create mode 100644 app/decorators/profile_decorator.rb create mode 100644 app/views/users/_profile_fields.html.erb diff --git a/app/controllers/stories_controller.rb b/app/controllers/stories_controller.rb index 37bf9a1b5..d368d890b 100644 --- a/app/controllers/stories_controller.rb +++ b/app/controllers/stories_controller.rb @@ -234,6 +234,7 @@ class StoriesController < ApplicationController # - Let's say it's `4`. On mobile it would display two rows: 1st with 3 badges and # 2nd with 1 badge (!) <-- and that would look off. @badges_limit = 6 + @profile = @user.profile.decorate set_surrogate_key_header "articles-user-#{@user.id}" set_user_json_ld diff --git a/app/decorators/profile_decorator.rb b/app/decorators/profile_decorator.rb new file mode 100644 index 000000000..d1bbb5f57 --- /dev/null +++ b/app/decorators/profile_decorator.rb @@ -0,0 +1,14 @@ +class ProfileDecorator < ApplicationDecorator + DEV_HEADER_FIELDS = %w[employment_title employer_name].freeze + + # Return a Hash of the profile fields that should be rendered for a given + # display area, e.g. :left_sidebar + def ui_attributes_for(area:) + names = ProfileField.public_send(area).pluck(:attribute_name) + # Temporary workaround: DEV specific header fields are hardcoded in the view + if SiteConfig.dev_to? + names -= DEV_HEADER_FIELDS + end + data.slice(*names).select { |_, v| v.present? } + end +end diff --git a/app/models/profile.rb b/app/models/profile.rb index b2e817b18..bd7d752ae 100644 --- a/app/models/profile.rb +++ b/app/models/profile.rb @@ -16,6 +16,7 @@ class Profile < ApplicationRecord brand_color2: :text_color_hex, display_email_on_profile: :email_public, display_looking_for_work_on_profile: :looking_for_work_publicly, + education: :education, git_lab_url: :gitlab_url, linked_in_url: :linkedin_url, recruiters_can_contact_me_about_job_opportunities: :contact_consent, diff --git a/app/views/users/_metadata.html.erb b/app/views/users/_metadata.html.erb index ca95284fd..1533a0493 100644 --- a/app/views/users/_metadata.html.erb +++ b/app/views/users/_metadata.html.erb @@ -1,34 +1,78 @@ -<% if @user.employment_title.present? || (@user.looking_for_work_publicly == true && @user.looking_for_work == true) || @user.education.present? %> -
- <% if @user.education.present? %> -
- Education -

<%= @user.education %>

-
- <% end %> - - <% if @user.employment_title.present? %> -
- Work -

- <%= @user.employment_title %> - <% if @user.employer_name.present? %> - at - <% if @user.employer_url.present? %> - <%= @user.employer_name %> - <% else %> - <%= @user.employer_name %> - <% end %> +<% if FeatureFlag.enabled?(:profile_admin) %> + <% if (header_fields = @profile.ui_attributes_for(area: :header)).present? %> +

+ <% header_fields.each do |title, value| %> +
+ + <%= sanitized_sidebar title.titleize %> + +

+ <%= sanitized_sidebar value %> +

+
+ <% end %> + <%# As we migrate to more generalized profiles, we don't want to break DEV %> + <% if SiteConfig.dev_to? %> + <% if @user.employment_title.present? || (@user.looking_for_work_publicly == true && @user.looking_for_work == true) %> + <% if @user.employment_title.present? %> +
+ Work +

+ <%= @user.employment_title %> + <% if @user.employer_name.present? %> + at + <% if @user.employer_url.present? %> + <%= @user.employer_name %> + <% else %> + <%= @user.employer_name %> + <% end %> + <% end %> +

+
<% end %> -

-
- <% end %> + <% if @user.looking_for_work_publicly == true && @user.looking_for_work == true %> +
+ Work status +

I'm looking for work!

+
+ <% end %> + <% end %> + <% end %> +
+ <% end %> +<% else %> + <% if @user.employment_title.present? || (@user.looking_for_work_publicly == true && @user.looking_for_work == true) || @user.education.present? %> +
+ <% if @user.education.present? %> +
+ Education +

<%= @user.education %>

+
+ <% end %> - <% if @user.looking_for_work_publicly == true && @user.looking_for_work == true %> -
- Work status -

I'm looking for work!

-
- <% end %> -
+ <% if @user.employment_title.present? %> +
+ Work +

+ <%= @user.employment_title %> + <% if @user.employer_name.present? %> + at + <% if @user.employer_url.present? %> + <%= @user.employer_name %> + <% else %> + <%= @user.employer_name %> + <% end %> + <% end %> +

+
+ <% end %> + + <% if @user.looking_for_work_publicly == true && @user.looking_for_work == true %> +
+ Work status +

I'm looking for work!

+
+ <% end %> +
+ <% end %> <% end %> diff --git a/app/views/users/_profile_fields.html.erb b/app/views/users/_profile_fields.html.erb new file mode 100644 index 000000000..e69de29bb diff --git a/app/views/users/_sidebar.html.erb b/app/views/users/_sidebar.html.erb index 1a886afb4..a59ddd6e7 100644 --- a/app/views/users/_sidebar.html.erb +++ b/app/views/users/_sidebar.html.erb @@ -32,52 +32,68 @@ <% end %> <% cache "user-profile-sidebar-profile-details-#{@user.id}-#{@user.profile_updated_at}", expires_in: 10.days do %> - <% if @user.mostly_work_with.present? %> -
-
-

Skills/languages

-
+ <% if FeatureFlag.enabled?(:profile_admin) %> + <% @profile.ui_attributes_for(area: :left_sidebar).each do |title, value| %> +
+
+

+ <%= sanitized_sidebar title.titleize %> +

+
-
- <%= sanitized_sidebar @user.mostly_work_with %> +
+ <%= sanitized_sidebar value %> +
-
- <% end %> + <% end %> + <% else %> + <% if @user.mostly_work_with.present? %> +
+
+

Skills/languages

+
- <% if @user.currently_learning.present? %> -
-
-

Learning/trying

-
- -
- <%= sanitized_sidebar @user.currently_learning %> +
+ <%= sanitized_sidebar @user.mostly_work_with %> +
-
- <% end %> + <% end %> - <% if @user.currently_hacking_on.present? %> -
-
-

Projects

-
+ <% if @user.currently_learning.present? %> +
+
+

Learning/trying

+
-
- <%= sanitized_sidebar @user.currently_hacking_on %> +
+ <%= sanitized_sidebar @user.currently_learning %> +
-
- <% end %> + <% end %> - <% if @user.available_for.present? %> -
-
-

Available for...

-
+ <% if @user.currently_hacking_on.present? %> +
+
+

Projects

+
-
- <%= sanitized_sidebar @user.available_for %> +
+ <%= sanitized_sidebar @user.currently_hacking_on %> +
-
+ <% end %> + + <% if @user.available_for.present? %> +
+
+

Available for...

+
+ +
+ <%= sanitized_sidebar @user.available_for %> +
+
+ <% end %> <% end %> <% end %> diff --git a/db/seeds.rb b/db/seeds.rb index 373f9659b..502c294c6 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -91,7 +91,6 @@ end ############################################################################## - num_users = 10 * SEEDS_MULTIPLIER users_in_random_order = seeder.create_if_none(User, num_users) do diff --git a/lib/data/dev_profile_fields.csv b/lib/data/dev_profile_fields.csv index b0b7d569f..4fd931a77 100644 --- a/lib/data/dev_profile_fields.csv +++ b/lib/data/dev_profile_fields.csv @@ -1,18 +1,18 @@ Display email on profile,check_box,,,Basic,settings_only,false -Website URL,text_field,https://yoursite.com,,Basic,header,true -Summary,text_area,A short bio...,,Basic,header,true +Website URL,text_field,https://yoursite.com,,Basic,settings_only,true +Summary,text_area,A short bio...,,Basic,settings_only,true Location,text_field,"Halifax, Nova Scotia",,Basic,header,true -Facebook URL,text_field,https://facebook.com/...,,Links,header,false -Youtube URL,text_field,https://www.youtube.com/channel/...,,Links,header,false -StackOverflow URL,text_field,https://stackoverflow.com/users/...,,Links,header,false -LinkedIn URL,text_field,https://www.linkedin.com/in/...,,Links,header,false -Behance URL,text_field,https://www.behance.net/...,,Links,header,false -Dribbble URL,text_field,https://dribbble.com/...,,Links,header,false -Medium URL,text_field,https://medium.com/@...,,Links,header,false -GitLab URL,text_field,https://gitlab.com/...,,Links,header,false -Instagram URL,text_field,https://www.instagram.com/...,,Links,header,false -Mastodon URL,text_field,https://...,,Links,header,false -Twitch URL,text_field,https://www.twitch.tv/...,,Links,header,false +Facebook URL,text_field,https://facebook.com/...,,Links,settings_only,false +Youtube URL,text_field,https://www.youtube.com/channel/...,,Links,settings_only,false +StackOverflow URL,text_field,https://stackoverflow.com/users/...,,Links,settings_only,false +LinkedIn URL,text_field,https://www.linkedin.com/in/...,,Links,settings_only,false +Behance URL,text_field,https://www.behance.net/...,,Links,settings_only,false +Dribbble URL,text_field,https://dribbble.com/...,,Links,settings_only,false +Medium URL,text_field,https://medium.com/@...,,Links,settings_only,false +GitLab URL,text_field,https://gitlab.com/...,,Links,settings_only,false +Instagram URL,text_field,https://www.instagram.com/...,,Links,settings_only,false +Mastodon URL,text_field,https://...,,Links,settings_only,false +Twitch URL,text_field,https://www.twitch.tv/...,,Links,settings_only,false Education,text_field,,,Work,header,false Employer name,text_field,Acme Inc.,,Work,header,false Employer URL,text_field,https://dev.com,,Work,header,false diff --git a/spec/system/user/user_edits_profile_spec.rb b/spec/system/user/user_edits_profile_spec.rb index 3cfdf9c72..7d24d5402 100644 --- a/spec/system/user/user_edits_profile_spec.rb +++ b/spec/system/user/user_edits_profile_spec.rb @@ -2,6 +2,25 @@ require "rails_helper" RSpec.describe "User edits their profile", type: :system do let(:user) { create(:user) } + let!(:profile_field_group) { create(:profile_field_group, name: "Ice Cream") } + let!(:left_sidebar_profile_field) do + create(:profile_field, + profile_field_group: profile_field_group, + label: "Preferred Ice Cream Flavor", + display_area: "left_sidebar") + end + let!(:header_profile_field) do + create(:profile_field, + profile_field_group: profile_field_group, + label: "Hate Ice Cream Flavor", + display_area: "header") + end + let!(:settings_only_profile_field) do + create(:profile_field, + profile_field_group: profile_field_group, + label: "Imaginary Ice Cream Flavor", + display_area: "settings_only") + end before do sign_in user @@ -26,4 +45,39 @@ RSpec.describe "User edits their profile", type: :system do expect(page).to have_css(".sticky") end end + + describe "editing admin created profile fields" do + before do + allow(FeatureFlag).to receive(:enabled?).with(:profile_admin).and_return(true) + Profile.refresh_attributes! + end + + it "renders profile fields" do + expect(page).to have_text(left_sidebar_profile_field.attribute_name.titleize) + expect(page).to have_text(header_profile_field.attribute_name.titleize) + expect(page).to have_text(settings_only_profile_field.attribute_name.titleize) + end + + it "reflects set profile fields in the interface" do + fill_in "profile[#{left_sidebar_profile_field.attribute_name}]", with: "chocolate" + fill_in "profile[#{header_profile_field.attribute_name}]", with: "pistachio" + fill_in "profile[#{settings_only_profile_field.attribute_name}]", with: "cthulhu" + click_button "Save" + + visit "/#{user.username}" + + expect(page).not_to have_text(settings_only_profile_field.attribute_name.titleize) + expect(page).not_to have_text("cthulhu") + + within(".crayons-layout__sidebar-left") do + expect(page).to have_text(left_sidebar_profile_field.attribute_name.titleize) + expect(page).to have_text("chocolate") + end + + within(".profile-header") do + expect(page).to have_text(header_profile_field.attribute_name.titleize) + expect(page).to have_text("pistachio") + end + end + end end