diff --git a/app/assets/images/website.svg b/app/assets/images/website.svg new file mode 100644 index 000000000..a9886a473 --- /dev/null +++ b/app/assets/images/website.svg @@ -0,0 +1,3 @@ + + + diff --git a/app/decorators/profile_decorator.rb b/app/decorators/profile_decorator.rb index d1bbb5f57..3f07ef9ec 100644 --- a/app/decorators/profile_decorator.rb +++ b/app/decorators/profile_decorator.rb @@ -1,14 +1,8 @@ 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 2bb1269f5..a013d4647 100644 --- a/app/models/profile.rb +++ b/app/models/profile.rb @@ -9,6 +9,30 @@ class Profile < ApplicationRecord store_attribute :data, :custom_attributes, :json, default: {} + SPECIAL_DISPLAY_ATTRIBUTES = %w[ + summary + employment_title + employer_name + employer_url + location + ].freeze + + SPECIAL_SOCIAL_LINK_ATTRIBUTES = %w[ + twitter_url + github_url + facebook_url + linkedin_url + youtube_url + instagram_url + behance_url + medium_url + stackoverflow_url + gitlab_url + twitch_url + mastodon_url + website_url + ].freeze + # NOTE: @citizen428 This is a temporary mapping so we don't break DEV during # profile migration/generalization work. MAPPED_ATTRIBUTES = { @@ -41,6 +65,14 @@ class Profile < ApplicationRecord (stored_attributes[:data] || []).map(&:to_s) end + def self.special_attributes + SPECIAL_DISPLAY_ATTRIBUTES + SPECIAL_SOCIAL_LINK_ATTRIBUTES + end + + def self.special_social_link_attributes + SPECIAL_SOCIAL_LINK_ATTRIBUTES.freeze + end + def custom_profile_attributes custom_profile_fields.pluck(:attribute_name) end diff --git a/app/models/user.rb b/app/models/user.rb index d201001c2..a3a0ae5dd 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -286,6 +286,14 @@ class User < ApplicationRecord summary end + def twitter_url + "https://twitter.com/#{twitter_username}" if twitter_username.present? + end + + def github_url + "https://github.com/#{github_username}" if github_username.present? + end + def set_remember_fields self.remember_token ||= self.class.remember_token if respond_to?(:remember_token) self.remember_created_at ||= Time.now.utc diff --git a/app/views/admin/profile_fields/index.html.erb b/app/views/admin/profile_fields/index.html.erb index eb5d192c3..e12037e38 100644 --- a/app/views/admin/profile_fields/index.html.erb +++ b/app/views/admin/profile_fields/index.html.erb @@ -1,4 +1,9 @@
+
+

+ Instructions on how to properly use this feature at this time. +

+
<%= render "add_group_modal" %> <%= render "grouped_profile_fields" %> <%= render "ungrouped_profile_fields" %> diff --git a/app/views/users/_metadata.html.erb b/app/views/users/_metadata.html.erb index d783a9b13..3180b8520 100644 --- a/app/views/users/_metadata.html.erb +++ b/app/views/users/_metadata.html.erb @@ -1,63 +1,31 @@ -<% 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? %> -
- 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 %> -
- <% end %> -<% else %> - <% if @user.employment_title.present? || @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 (header_fields = @profile.ui_attributes_for(area: :header)).present? %> +

+ <% header_fields.each do |title, value| %> + <% next if Profile.special_attributes.include?(title) %> +
+ + <%= sanitized_sidebar title.titleize %> + +

+ <%= sanitized_sidebar value %> +

+
+ <% 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 %> + <% end %> +

+
+ <% end %> +
<% end %> diff --git a/app/views/users/_sidebar.html.erb b/app/views/users/_sidebar.html.erb index a59ddd6e7..5e6c6d8ba 100644 --- a/app/views/users/_sidebar.html.erb +++ b/app/views/users/_sidebar.html.erb @@ -32,68 +32,18 @@ <% end %> <% cache "user-profile-sidebar-profile-details-#{@user.id}-#{@user.profile_updated_at}", expires_in: 10.days do %> - <% if FeatureFlag.enabled?(:profile_admin) %> - <% @profile.ui_attributes_for(area: :left_sidebar).each do |title, value| %> -
-
-

- <%= sanitized_sidebar title.titleize %> -

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

+ <%= sanitized_sidebar title.titleize %> +

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

Skills/languages

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

Learning/trying

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

Projects

-
- -
- <%= 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/app/views/users/show.html.erb b/app/views/users/show.html.erb index 3687924a3..746fffdc2 100644 --- a/app/views/users/show.html.erb +++ b/app/views/users/show.html.erb @@ -74,75 +74,10 @@ <% end %> - <% if @user.twitter_username? %> - - <%= inline_svg_tag("twitter.svg", class: "crayons-icon", aria: true, title: "Twitter logo") %> - - <% end %> - <% if @user.github_username? %> - - <%= inline_svg_tag("github.svg", class: "crayons-icon", aria: true, title: "GitHub logo") %> - - <% end %> - <% if SiteConfig.dev_to? %> - <% if @user.mastodon_url.present? %> - - <%= inline_svg_tag("mastodon.svg", class: "crayons-icon", aria: true, title: "Mastodon logo") %> - - <% end %> - <% if @user.facebook_url.present? %> - - <%= inline_svg_tag("facebook.svg", class: "crayons-icon", aria: true, title: "Facebook logo") %> - - <% end %> - <% if @user.youtube_url.present? %> - - <%= inline_svg_tag("youtube.svg", class: "crayons-icon", aria: true, title: "Youtube logo") %> - - <% end %> - <% if @user.linkedin_url.present? %> - - <%= inline_svg_tag("linkedin.svg", class: "crayons-icon", aria: true, title: "LinkedIn logo") %> - - <% end %> - <% if @user.behance_url.present? %> - - <%= inline_svg_tag("behance.svg", class: "crayons-icon", aria: true, title: "Behance logo") %> - - <% end %> - <% if @user.stackoverflow_url.present? %> - - <%= inline_svg_tag("stackoverflow.svg", class: "crayons-icon", aria: true, title: "StackOverflow logo") %> - - <% end %> - <% if @user.dribbble_url.present? %> - - <%= inline_svg_tag("dribbble.svg", class: "crayons-icon", aria: true, title: "Dribbble logo") %> - - <% end %> - <% if @user.medium_url.present? %> - - <%= inline_svg_tag("medium.svg", class: "crayons-icon", aria: true, title: "Medium logo") %> - - <% end %> - <% if @user.gitlab_url.present? %> - - <%= inline_svg_tag("gitlab.svg", class: "crayons-icon", aria: true, title: "GitLab logo") %> - - <% end %> - <% if @user.instagram_url.present? %> - - <%= inline_svg_tag("instagram.svg", class: "crayons-icon", aria: true, title: "Instagram logo") %> - - <% end %> - <% if @user.twitch_url.present? %> - - <%= inline_svg_tag("twitch.svg", class: "crayons-icon", aria: true, title: "Twitch logo") %> - - <% end %> - <% if @user.website_url.present? %> - - <%= inline_svg_tag("external.svg", class: "crayons-icon", aria: true, title: "External link icon") %> + <% Profile.special_social_link_attributes.each do |attribute| %> + <% if @user.send(attribute).present? %> + + <%= inline_svg_tag("#{attribute.gsub("_url","")}.svg", class: "crayons-icon", aria: true, title: "#{attribute.split("_").first.titleize} logo") %> <% end %> <% end %> diff --git a/lib/data_update_scripts/20201223013903_set_proper_display_area_for_profile_fields.rb b/lib/data_update_scripts/20201223013903_set_proper_display_area_for_profile_fields.rb new file mode 100644 index 000000000..5ab2d2050 --- /dev/null +++ b/lib/data_update_scripts/20201223013903_set_proper_display_area_for_profile_fields.rb @@ -0,0 +1,28 @@ +module DataUpdateScripts + class SetProperDisplayAreaForProfileFields + def run + ProfileField.where(attribute_name: %w[brand_color1 + brand_color2 + recruiters_can_contact_me_about_job_opportunities + display_email_on_profile + twitter_url + github_url + facebook_url + linkedin_url + youtube_url + instagram_url + behance_url + medium_url + stackoverflow_url + gitlab_url + twitch_url + mastodon_url + website_url]) + .update_all(display_area: "settings_only") + ProfileField.where.not(display_area: "settings_only").update_all(display_area: "header") + ProfileField.where(attribute_name: + %w[currently_hacking_on currently_learning mostly_work_with available_for]) + .update_all(display_area: "left_sidebar") + end + end +end diff --git a/spec/lib/data_update_scripts/set_proper_display_area_for_profile_fields_spec.rb b/spec/lib/data_update_scripts/set_proper_display_area_for_profile_fields_spec.rb new file mode 100644 index 000000000..ecce38910 --- /dev/null +++ b/spec/lib/data_update_scripts/set_proper_display_area_for_profile_fields_spec.rb @@ -0,0 +1,15 @@ +require "rails_helper" +require Rails.root.join( + "lib/data_update_scripts/20201223013903_set_proper_display_area_for_profile_fields.rb", +) + +describe DataUpdateScripts::SetProperDisplayAreaForProfileFields do + it "migrates profile fields to proper areas" do + # Run the script + described_class.new.run + expect(ProfileField.find_by(attribute_name: "instagram_url").display_area) + .to eq("settings_only") + expect(ProfileField.find_by(attribute_name: "education").display_area).to eq("header") + expect(ProfileField.find_by(attribute_name: "currently_learning").display_area).to eq("left_sidebar") + end +end diff --git a/spec/requests/user/user_profile_spec.rb b/spec/requests/user/user_profile_spec.rb index a1c521c80..ac8e7f8e8 100644 --- a/spec/requests/user/user_profile_spec.rb +++ b/spec/requests/user/user_profile_spec.rb @@ -91,6 +91,40 @@ RSpec.describe "UserProfiles", type: :request do expect(response.body).not_to include "author-payment-pointer" end + it "renders sidebar profile field elements in sidebar" do + create(:profile_field, label: "whoaaaa", display_area: "left_sidebar") + get "/#{user.username}" + # Ensure this comes after the start of the sidebar element + expect(response.body.split("Whoaaaa").first).to include "crayons-layout__sidebar-left" + end + + it "does not render settings_only on page" do + create(:profile_field, label: "whoaaaa", display_area: "settings_only") + get "/#{user.username}" + expect(response.body).not_to include "Whoaaaa" + end + + it "does not render special display header elements naively" do + user.location = "hawaii" + user.save + get "/#{user.username}" + # Does not include the word, but does include the SVG + expect(response.body).not_to include "

Location

" + expect(response.body).to include user.location + expect(response.body).to include "M18.364 17.364L12 23.728l-6.364-6.364a9 9 0 1112.728 0zM12 13a2 2 0 100-4 2 2 0" + end + + it "does not render special display social link elements naively" do + user.instagram_url = "https://instagram.com/whoa" + user.save + get "/#{user.username}" + # Does not include the word, but does include the SVG + expect(response.body).not_to include "

Instagram" + expect(response.body).to include "Instagram logo" + expect(response.body).to include user.instagram_url + expect(response.body).to include "M12 2c2.717 0 3.056.01 4.122.06 1.065.05 1.79.217 2.428.465.66.254" + end + context "when organization" do it "renders organization page if org" do get organization.path diff --git a/spec/services/profile_fields/import_from_csv_spec.rb b/spec/services/profile_fields/import_from_csv_spec.rb index 73fe4463d..7c57558f9 100644 --- a/spec/services/profile_fields/import_from_csv_spec.rb +++ b/spec/services/profile_fields/import_from_csv_spec.rb @@ -16,6 +16,7 @@ RSpec.describe ProfileFields::ImportFromCsv do expect(field.placeholder_text).to eq "John Doe" expect(field.description).to be_nil expect(field.profile_field_group.name).to eq "Basic" + expect(field.display_area).to eq "header" end it "handles missing placeholder_texts", :aggregate_failures do @@ -24,6 +25,7 @@ RSpec.describe ProfileFields::ImportFromCsv do expect(field.placeholder_text).to be_nil expect(field.description).to eq "Programming languages" expect(field.profile_field_group.name).to eq "Coding" + expect(field.display_area).to eq "left_sidebar" end it "handles commas in correctly quoted fields", :aggregate_failures do @@ -32,6 +34,7 @@ RSpec.describe ProfileFields::ImportFromCsv do expect(field.placeholder_text).to eq "#000000" expect(field.description).to eq "Used for backgrounds, borders etc." expect(field.profile_field_group.name).to eq "Branding" + expect(field.display_area).to eq "settings_only" end end end