[deploy] Dynamic frontend for the sidebar navigation Items (#10754)
* feat: configure the frontend for sidebar nav links * chore: add a comment * changes to the admin interface * feat: move the temporary task to be in the rake tasks and use it in the dev seeds * feat: use the task in the rake seeds * refactor: reuse the form across two modals * refactor: use the form partial * feat: change the modal to be large * fix: naming * Update db/seeds.rb Co-authored-by: Michael Kohl <me@citizen428.net> * chore: make the file readable * chore: removed the if else as the rake task was run on all forems + i sent out a message to new communities * oops * refactor: add a scope * chore: oops removed this * feat: add navigation links specs * spec: fix two failing ones Co-authored-by: Michael Kohl <me@citizen428.net>
This commit is contained in:
parent
ee7ef33c0b
commit
66b14fc0bf
16 changed files with 294 additions and 196 deletions
|
|
@ -96,3 +96,8 @@
|
|||
.admin-navigation-links {
|
||||
width: 240px;
|
||||
}
|
||||
|
||||
.admin-navigation-links .crayons-icon svg {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -115,6 +115,11 @@
|
|||
max-height: 420px;
|
||||
}
|
||||
|
||||
.sidebar-navigation-links .crayons-icon svg {
|
||||
height: 24px;
|
||||
weight: 24px;
|
||||
}
|
||||
|
||||
@keyframes fade-in {
|
||||
0% {
|
||||
opacity: 0;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ module Admin
|
|||
layout "admin"
|
||||
|
||||
def index
|
||||
@navigation_links = NavigationLink.order(position: :asc, name: :asc)
|
||||
@navigation_links = NavigationLink.ordered
|
||||
end
|
||||
|
||||
def create
|
||||
|
|
|
|||
|
|
@ -5,4 +5,6 @@ class NavigationLink < ApplicationRecord
|
|||
validates :url, url: { schemes: %w[https http] }, uniqueness: { scope: :name }
|
||||
validates :icon, format: SVG_REGEXP
|
||||
validates :display_only_when_signed_in, inclusion: { in: [true, false] }
|
||||
|
||||
scope :ordered, -> { order(position: :asc, name: :asc) }
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
<button class="btn btn-primary" type="button" onclick="toggleNavigationLinkModal()">
|
||||
<button class="btn btn-primary ml-7" type="button" onclick="toggleNavigationLinkModal()">
|
||||
Add Navigation Link
|
||||
</button>
|
||||
|
||||
<div id="add-navigation-link-modal" class="hidden">
|
||||
<div class="crayons-modal crayons-modal--s">
|
||||
<div class="crayons-modal crayons-modal--l">
|
||||
<div class="crayons-modal__box">
|
||||
<header class="crayons-modal__box__header">
|
||||
<h2>Add Navigation Link</h2>
|
||||
|
|
@ -17,30 +17,10 @@
|
|||
<div class="form-group grid p-6 mb-6 gap-1">
|
||||
<div class="form-group grid p-6 mb-6 gap-1">
|
||||
<%= form_for(NavigationLink.new, url: admin_navigation_links_path) do |form| %>
|
||||
<div class="form-group">
|
||||
<%= form.label :name %>
|
||||
<%= form.text_field :name, class: "form-control" %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= form.label :url %>
|
||||
<%= form.text_field :url, class: "form-control" %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= form.label :icon %>
|
||||
<%= form.text_area :icon, class: "form-control" %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= form.label :position %>
|
||||
<%= form.number_field :position, class: "form-control" %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= form.check_box :display_only_when_signed_in %>
|
||||
<%= form.label :display_only_when_signed_in %>
|
||||
</div>
|
||||
<%= render "form", form: form %>
|
||||
<%= form.submit "Add link", class: "crayons-btn" %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
</div>
|
||||
|
||||
<div id="edit-navigation-link-<%= link[:id] %>-modal" class="hidden">
|
||||
<div class="crayons-modal crayons-modal--s">
|
||||
<div class="crayons-modal crayons-modal--l">
|
||||
<div class="crayons-modal__box">
|
||||
<header class="crayons-modal__box__header">
|
||||
<h2>Edit Link</h2>
|
||||
|
|
@ -16,26 +16,7 @@
|
|||
<div class="crayons-modal__box__body">
|
||||
<div class="form-group grid p-6 mb-6 gap-1">
|
||||
<%= form_for [:admin, link] do |form| %>
|
||||
<div class="form-group">
|
||||
<%= form.label :name %>
|
||||
<%= form.text_field :name, class: "form-control" %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= form.label :url %>
|
||||
<%= form.text_field :url, class: "form-control" %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= form.label :icon %>
|
||||
<%= form.text_field :icon, class: "form-control" %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= form.label :position %>
|
||||
<%= form.number_field :position, class: "form-control" %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= form.check_box :display_only_when_signed_in %>
|
||||
<%= form.label :display_only_when_signed_in %>
|
||||
</div>
|
||||
<%= render "form", form: form %>
|
||||
<%= form.submit class: "btn btn-primary" %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
|
|||
25
app/views/admin/navigation_links/_form.html.erb
Normal file
25
app/views/admin/navigation_links/_form.html.erb
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
<div class="form-group">
|
||||
<%= form.label :name %>
|
||||
<%= form.text_field :name, class: "form-control" %>
|
||||
<div class="alert alert-info">A friendly name for the navigation link</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= form.label :url %>
|
||||
<%= form.text_field :url, class: "form-control" %>
|
||||
<div class="alert alert-info">A full URL for the link</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= form.label :icon %>
|
||||
<%= form.text_area :icon, class: "form-control" %>
|
||||
<div class="alert alert-info">An SVG icon should be pasted in the textarea</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= form.label :position %>
|
||||
<%= form.number_field :position, class: "form-control" %>
|
||||
<div class="alert alert-info">Detemines the order placement of the links in the sidebar</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= form.check_box :display_only_when_signed_in %>
|
||||
<%= form.label :display_only_when_signed_in %>
|
||||
<div class="alert alert-info">Determines whether the link should only be shown after the user has signed into their account.</div>
|
||||
</div>
|
||||
|
|
@ -1,23 +1,27 @@
|
|||
<%= render "add_navigation_link_modal" %>
|
||||
<% @navigation_links.each do |link| %>
|
||||
<div class="flex pt-5 items-center">
|
||||
<div class="mr-5"><%= link.position %></div>
|
||||
<div class="admin-navigation-links">
|
||||
<a href="<%= link[:url] %>" class="crayons-link crayons-link--block bg-base-20">
|
||||
<div class="crayons-icon crayons-icon--default">
|
||||
<%= link[:icon].html_safe %>
|
||||
</div>
|
||||
<%= link[:name] %><span id="reading-list-count" class="crayons-indicator"></span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="ml-5">
|
||||
<div class="my-5"> Configure the left sidebar navigation links that appear at <a href="<%= app_url %>"<%= app_url %>""><%= app_url %></a> using the form below:</div>
|
||||
|
||||
<div class="flex items-center mx-5">
|
||||
<div class="mx-3">
|
||||
<%= render partial: "edit_navigation_link_modal", locals: { link: link } %>
|
||||
<%= render "add_navigation_link_modal" %>
|
||||
<% @navigation_links.each do |link| %>
|
||||
<div class="flex pt-5 items-center">
|
||||
<div class="mr-5"><%= link[:position] %></div>
|
||||
<div class="admin-navigation-links">
|
||||
<a href="<%= link[:url] %>" class="crayons-link crayons-link--block bg-base-20">
|
||||
<div class="crayons-icon crayons-icon--default">
|
||||
<%= link[:icon].html_safe %>
|
||||
</div>
|
||||
<%= link[:name] %><span id="reading-list-count" class="crayons-indicator"></span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="mx-3">
|
||||
<%= link_to "Delete", admin_navigation_link_path(link), data: { confirm: "Are you sure?" }, method: :delete, class: "color-accent-danger" %>
|
||||
|
||||
<div class="flex items-center mx-5">
|
||||
<div class="mx-3">
|
||||
<%= render partial: "edit_navigation_link_modal", locals: { link: link } %>
|
||||
</div>
|
||||
<div class="mx-3">
|
||||
<%= link_to "Delete", admin_navigation_link_path(link), data: { confirm: "Are you sure?" }, method: :delete, class: "color-accent-danger" %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -24,70 +24,21 @@
|
|||
</a>
|
||||
<% end %>
|
||||
|
||||
<% if user_signed_in? %>
|
||||
<a href="<%= readinglist_path %>" class="crayons-link crayons-link--block">
|
||||
<%= inline_svg_tag("twemoji/drawer.svg", aria: true, class: "crayons-icon crayons-icon--default", title: "Reading list") %>
|
||||
Reading list <span id="reading-list-count" class="crayons-indicator"></span>
|
||||
</a>
|
||||
<% end %>
|
||||
<a href="<%= listings_path %>" class="crayons-link crayons-link--block">
|
||||
<%= inline_svg_tag("twemoji/listing.svg", aria: true, class: "crayons-icon crayons-icon--default", title: "Listings") %>
|
||||
Listings
|
||||
</a>
|
||||
<a href="<%= pod_path %>" class="crayons-link crayons-link--block">
|
||||
<%= inline_svg_tag("twemoji/mic.svg", aria: true, class: "crayons-icon crayons-icon--default", title: "Podcasts") %>
|
||||
Podcasts
|
||||
</a>
|
||||
<a href="<%= videos_path %>" class="crayons-link crayons-link--block">
|
||||
<%= inline_svg_tag("twemoji/camera.svg", aria: true, class: "crayons-icon crayons-icon--default", title: "Videos") %>
|
||||
Videos
|
||||
</a>
|
||||
<a href="<%= tags_path %>" class="crayons-link crayons-link--block">
|
||||
<%= inline_svg_tag("twemoji/tag.svg", aria: true, class: "crayons-icon crayons-icon--default", title: "Tags") %>
|
||||
Tags
|
||||
</a>
|
||||
|
||||
<a href="javascript:void(0)" class="crayons-link crayons-link--secondary crayons-link--block crayons-link--block--indented fs-s" id="main-nav-more-trigger">More...</a>
|
||||
|
||||
<div class="hidden" id="main-nav-more">
|
||||
<a href="/code-of-conduct" class="crayons-link crayons-link--block">
|
||||
<%= inline_svg_tag("twemoji/thumb-up.svg", aria: true, class: "crayons-icon crayons-icon--default", title: "Code of Conduct") %>
|
||||
Code of Conduct
|
||||
</a>
|
||||
<a href="/faq" class="crayons-link crayons-link--block">
|
||||
<%= inline_svg_tag("twemoji/bulb.svg", aria: true, class: "crayons-icon crayons-icon--default", title: "FAQ") %>
|
||||
FAQ
|
||||
</a>
|
||||
<% if SiteConfig.shop_url.present? %>
|
||||
<a href="<%= SiteConfig.shop_url %>" class="crayons-link crayons-link--block">
|
||||
<%= inline_svg_tag("twemoji/shopping.svg", aria: true, class: "crayons-icon crayons-icon--default", title: "Shop") %>
|
||||
<%= community_name %> Shop
|
||||
</a>
|
||||
<div class="sidebar-navigation-links">
|
||||
<% NavigationLink.ordered[0..4].each do |link| %>
|
||||
<%= render "articles/sidebar_nav_link", link: link %>
|
||||
<% end %>
|
||||
<a href="/sponsors" class="crayons-link crayons-link--block">
|
||||
<%= inline_svg_tag("twemoji/heart.svg", aria: true, class: "crayons-icon crayons-icon--default", title: "Sponsors") %>
|
||||
Sponsors
|
||||
</a>
|
||||
<a href="/about" class="crayons-link crayons-link--block">
|
||||
<%= inline_svg_tag("rainbowdev.svg", aria: true, width: 24, height: 24, class: "crayons-icon crayons-icon--default p-1", title: "About") %>
|
||||
About
|
||||
</a>
|
||||
<a href="/privacy" class="crayons-link crayons-link--block">
|
||||
<%= inline_svg_tag("twemoji/smart.svg", aria: true, class: "crayons-icon crayons-icon--default", title: "Privacy policy") %>
|
||||
Privacy policy
|
||||
</a>
|
||||
<a href="/terms" class="crayons-link crayons-link--block">
|
||||
<%= inline_svg_tag("twemoji/look.svg", aria: true, class: "crayons-icon crayons-icon--default", title: "Terms of use") %>
|
||||
Terms of use
|
||||
</a>
|
||||
<a href="/contact" class="crayons-link crayons-link--block">
|
||||
<%= inline_svg_tag("twemoji/contact.svg", aria: true, class: "crayons-icon crayons-icon--default", title: "Contact") %>
|
||||
Contact
|
||||
</a>
|
||||
<div class="flex justify-around p-4 mt-4 border-solid border-0 border-t-1 border-base-10">
|
||||
<%= render partial: "layouts/social_media" %>
|
||||
</div>
|
||||
|
||||
<% if NavigationLink.all.length > 5 %>
|
||||
<a href="javascript:void(0)" class="crayons-link crayons-link--secondary crayons-link--block crayons-link--block--indented fs-s" id="main-nav-more-trigger">More...</a>
|
||||
|
||||
<div class="hidden" id="main-nav-more">
|
||||
<% NavigationLink.ordered[5..].each do |link| %>
|
||||
<%= render "articles/sidebar_nav_link", link: link %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</nav>
|
||||
|
||||
<nav class="sidebar-tags-browser mb-6 overflow-y-auto scrolling-touch" aria-label="Secondary sidebar nav">
|
||||
|
|
|
|||
11
app/views/articles/_sidebar_nav_link.html.erb
Normal file
11
app/views/articles/_sidebar_nav_link.html.erb
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<% if !link.display_only_when_signed_in || (link.display_only_when_signed_in && user_signed_in?) %>
|
||||
<a href="<%= link.url %>" class="sidebar-navigation-link crayons-link crayons-link--block">
|
||||
<span class="crayons-icon crayons-icon--default" title="Listings">
|
||||
<%= link.icon.html_safe %>
|
||||
</span>
|
||||
<%= link.name %>
|
||||
<% if link.url.include?("readinglist") %>
|
||||
<span id="reading-list-count" class="crayons-indicator"></span>
|
||||
<% end %>
|
||||
</a>
|
||||
<% end %>
|
||||
|
|
@ -574,6 +574,12 @@ end
|
|||
|
||||
##############################################################################
|
||||
|
||||
seeder.create_if_none(NavigationLink) do
|
||||
Rake::Task["navigation_links:update"].invoke
|
||||
end
|
||||
|
||||
##############################################################################
|
||||
|
||||
puts <<-ASCII
|
||||
|
||||
```````````````````````````````````````````````````````````````````````````
|
||||
|
|
|
|||
105
lib/tasks/add_navigation_links.rake
Normal file
105
lib/tasks/add_navigation_links.rake
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
# rubocop:disable Metrics/BlockLength
|
||||
namespace :navigation_links do
|
||||
desc "Update DEV's navigation_links"
|
||||
task update: :environment do
|
||||
protocol = ApplicationConfig["APP_PROTOCOL"].freeze
|
||||
domain = Rails.application&.initialized? ? SiteConfig.app_domain : ApplicationConfig["APP_DOMAIN"]
|
||||
base_url = "#{protocol}#{domain}".freeze
|
||||
|
||||
reading_icon = File.read(Rails.root.join("app/assets/images/twemoji/drawer.svg")).freeze
|
||||
thumb_up_icon = File.read(Rails.root.join("app/assets/images/twemoji/thumb-up.svg")).freeze
|
||||
smart_icon = File.read(Rails.root.join("app/assets/images/twemoji/smart.svg")).freeze
|
||||
look_icon = File.read(Rails.root.join("app/assets/images/twemoji/look.svg")).freeze
|
||||
contact_icon = File.read(Rails.root.join("app/assets/images/twemoji/contact.svg")).freeze
|
||||
|
||||
# we can probably remove these icons once they in the database
|
||||
listing_icon = File.read(Rails.root.join("app/assets/images/twemoji/listing.svg")).freeze
|
||||
mic_icon = File.read(Rails.root.join("app/assets/images/twemoji/mic.svg")).freeze
|
||||
camera_icon = File.read(Rails.root.join("app/assets/images/twemoji/camera.svg")).freeze
|
||||
tag_icon = File.read(Rails.root.join("app/assets/images/twemoji/tag.svg")).freeze
|
||||
bulb_icon = File.read(Rails.root.join("app/assets/images/twemoji/bulb.svg")).freeze
|
||||
shopping_icon = File.read(Rails.root.join("app/assets/images/twemoji/shopping.svg")).freeze
|
||||
heart_icon = File.read(Rails.root.join("app/assets/images/twemoji/heart.svg")).freeze
|
||||
rainbowdev = File.read(Rails.root.join("app/assets/images/rainbowdev.svg")).freeze
|
||||
|
||||
NavigationLink.where(url: "#{base_url}/readinglist").first_or_create(
|
||||
name: "Reading List",
|
||||
icon: reading_icon,
|
||||
display_only_when_signed_in: true,
|
||||
position: 0,
|
||||
)
|
||||
NavigationLink.where(url: "#{base_url}/listings").first_or_create(
|
||||
name: "Listings",
|
||||
icon: listing_icon,
|
||||
display_only_when_signed_in: false,
|
||||
position: 1,
|
||||
)
|
||||
NavigationLink.where(url: "#{base_url}/pod").first_or_create(
|
||||
name: "Podcasts",
|
||||
icon: mic_icon,
|
||||
display_only_when_signed_in: false,
|
||||
position: 2,
|
||||
)
|
||||
NavigationLink.where(url: "#{base_url}/videos").first_or_create(
|
||||
name: "Videos",
|
||||
icon: camera_icon,
|
||||
display_only_when_signed_in: false,
|
||||
position: 3,
|
||||
)
|
||||
NavigationLink.where(url: "#{base_url}/tags").first_or_create(
|
||||
name: "Tags",
|
||||
icon: tag_icon,
|
||||
display_only_when_signed_in: false,
|
||||
position: 4,
|
||||
)
|
||||
NavigationLink.where(url: "#{base_url}/code-of-conduct").first_or_create(
|
||||
name: "Code of Conduct",
|
||||
icon: thumb_up_icon,
|
||||
display_only_when_signed_in: false,
|
||||
position: 5,
|
||||
)
|
||||
NavigationLink.where(url: "#{base_url}/faq").first_or_create(
|
||||
name: "FAQ",
|
||||
icon: bulb_icon,
|
||||
display_only_when_signed_in: false,
|
||||
position: 6,
|
||||
)
|
||||
NavigationLink.where(url: "https://shop.dev.to/").first_or_create(
|
||||
name: "DEV Shop",
|
||||
icon: shopping_icon,
|
||||
display_only_when_signed_in: false,
|
||||
position: 7,
|
||||
)
|
||||
NavigationLink.where(url: "#{base_url}/sponsors").first_or_create(
|
||||
name: "Sponsors",
|
||||
icon: heart_icon,
|
||||
display_only_when_signed_in: false,
|
||||
position: 8,
|
||||
)
|
||||
NavigationLink.where(url: "#{base_url}/about").first_or_create(
|
||||
name: "About",
|
||||
icon: rainbowdev,
|
||||
display_only_when_signed_in: false,
|
||||
position: 9,
|
||||
)
|
||||
NavigationLink.where(url: "#{base_url}/privacy").first_or_create(
|
||||
name: "Privacy Policy",
|
||||
icon: smart_icon,
|
||||
display_only_when_signed_in: false,
|
||||
position: 10,
|
||||
)
|
||||
NavigationLink.where(url: "#{base_url}/terms").first_or_create(
|
||||
name: "Terms of use",
|
||||
icon: look_icon,
|
||||
display_only_when_signed_in: false,
|
||||
position: 11,
|
||||
)
|
||||
NavigationLink.where(url: "#{base_url}/contact").first_or_create(
|
||||
name: "Contact",
|
||||
icon: contact_icon,
|
||||
display_only_when_signed_in: false,
|
||||
position: 12,
|
||||
)
|
||||
end
|
||||
end
|
||||
# rubocop:enable Metrics/BlockLength
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
# rubocop:disable Metrics/BlockLength
|
||||
namespace :temporary do
|
||||
namespace :navigation_links do
|
||||
desc "Update DEV's navigation_links"
|
||||
task update_links: :environment do
|
||||
protocol = ApplicationConfig["APP_PROTOCOL"].freeze
|
||||
domain = Rails.application&.initialized? ? SiteConfig.app_domain : ApplicationConfig["APP_DOMAIN"]
|
||||
base_url = "#{protocol}#{domain}".freeze
|
||||
|
||||
reading_icon = File.read(Rails.root.join("app/assets/images/twemoji/drawer.svg")).freeze
|
||||
thumb_up_icon = File.read(Rails.root.join("app/assets/images/twemoji/thumb-up.svg")).freeze
|
||||
smart_icon = File.read(Rails.root.join("app/assets/images/twemoji/smart.svg")).freeze
|
||||
look_icon = File.read(Rails.root.join("app/assets/images/twemoji/look.svg")).freeze
|
||||
contact_icon = File.read(Rails.root.join("app/assets/images/twemoji/contact.svg")).freeze
|
||||
|
||||
# we can probably remove these icons once they in the database
|
||||
listing_icon = File.read(Rails.root.join("app/assets/images/twemoji/listing.svg")).freeze
|
||||
mic_icon = File.read(Rails.root.join("app/assets/images/twemoji/mic.svg")).freeze
|
||||
camera_icon = File.read(Rails.root.join("app/assets/images/twemoji/camera.svg")).freeze
|
||||
tag_icon = File.read(Rails.root.join("app/assets/images/twemoji/tag.svg")).freeze
|
||||
bulb_icon = File.read(Rails.root.join("app/assets/images/twemoji/bulb.svg")).freeze
|
||||
shopping_icon = File.read(Rails.root.join("app/assets/images/twemoji/shopping.svg")).freeze
|
||||
heart_icon = File.read(Rails.root.join("app/assets/images/twemoji/heart.svg")).freeze
|
||||
rainbowdev = File.read(Rails.root.join("app/assets/images/rainbowdev.svg")).freeze
|
||||
|
||||
NavigationLink.where(url: "#{base_url}/readinglist").first_or_create(name: "Reading List", icon: reading_icon,
|
||||
display_only_when_signed_in: true,
|
||||
position: 0)
|
||||
NavigationLink.where(url: "#{base_url}/listings").first_or_create(name: "Listings", icon: listing_icon,
|
||||
display_only_when_signed_in: false, position: 1)
|
||||
NavigationLink.where(url: "#{base_url}/pod").first_or_create(name: "Podcasts", icon: mic_icon,
|
||||
display_only_when_signed_in: false, position: 2)
|
||||
NavigationLink.where(url: "#{base_url}/videos").first_or_create(name: "Videos", icon: camera_icon,
|
||||
display_only_when_signed_in: false, position: 3)
|
||||
NavigationLink.where(url: "#{base_url}/tags").first_or_create(name: "Tags", icon: tag_icon,
|
||||
display_only_when_signed_in: false, position: 4)
|
||||
NavigationLink.where(url: "#{base_url}/code-of-conduct").first_or_create(name: "Code of Conduct",
|
||||
icon: thumb_up_icon,
|
||||
display_only_when_signed_in: false,
|
||||
position: 5)
|
||||
NavigationLink.where(url: "#{base_url}/faq").first_or_create(name: "FAQ", icon: bulb_icon,
|
||||
display_only_when_signed_in: false, position: 6)
|
||||
NavigationLink.where(url: "https://shop.dev.to/").first_or_create(name: "DEV Shop", icon: shopping_icon,
|
||||
display_only_when_signed_in: false, position: 7)
|
||||
NavigationLink.where(url: "#{base_url}/sponsors").first_or_create(name: "Sponsors", icon: heart_icon,
|
||||
display_only_when_signed_in: false, position: 8)
|
||||
NavigationLink.where(url: "#{base_url}/about").first_or_create(name: "About", icon: rainbowdev,
|
||||
display_only_when_signed_in: false, position: 9)
|
||||
NavigationLink.where(url: "#{base_url}/privacy").first_or_create(name: "Privacy Policy", icon: smart_icon,
|
||||
display_only_when_signed_in: false, position: 10)
|
||||
NavigationLink.where(url: "#{base_url}/terms").first_or_create(name: "Terms of use", icon: look_icon,
|
||||
display_only_when_signed_in: false, position: 11)
|
||||
NavigationLink.where(url: "#{base_url}/contact").first_or_create(name: "Contact", icon: contact_icon,
|
||||
display_only_when_signed_in: false, position: 12)
|
||||
end
|
||||
end
|
||||
end
|
||||
# rubocop:enable Metrics/BlockLength
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
FactoryBot.define do
|
||||
factory :navigation_link do
|
||||
name { "Test Link" }
|
||||
url { "https://www.test.com" }
|
||||
name { "#{Faker::Book.title} #{rand(1000)}" }
|
||||
url { "#{Faker::Internet.url}/#{rand(1000)}" }
|
||||
icon { "<svg xmlns='http://www.w3.org/2000/svg'/></svg>" }
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ RSpec.describe "NavigationLinks", type: :request do
|
|||
expect(response).to redirect_to admin_navigation_links_path
|
||||
end
|
||||
|
||||
it "creates a profile_field_group" do
|
||||
it "creates a navigation link" do
|
||||
expect do
|
||||
post admin_navigation_links_path, params: { navigation_link: new_navigation_link }
|
||||
end.to change { NavigationLink.all.count }.by(1)
|
||||
|
|
|
|||
|
|
@ -32,6 +32,28 @@ RSpec.describe "User visits a homepage", type: :system do
|
|||
expect(page).to have_selector(selector, visible: :hidden)
|
||||
end
|
||||
end
|
||||
|
||||
describe "navigation_links" do
|
||||
before do
|
||||
create(:navigation_link,
|
||||
name: "Listings",
|
||||
icon: "<svg xmlns='http://www.w3.org/2000/svg'/></svg>",
|
||||
display_only_when_signed_in: true,
|
||||
position: 1)
|
||||
create(:navigation_link,
|
||||
name: "Podcasts",
|
||||
icon: "<svg xmlns='http://www.w3.org/2000/svg'/></svg>",
|
||||
display_only_when_signed_in: false,
|
||||
position: nil)
|
||||
end
|
||||
|
||||
it "shows the correct count of links" do
|
||||
visit "/"
|
||||
within(".sidebar-navigation-links") do
|
||||
expect(page).to have_selector(".sidebar-navigation-link", count: 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when logged in user" do
|
||||
|
|
@ -106,24 +128,83 @@ RSpec.describe "User visits a homepage", type: :system do
|
|||
end
|
||||
end
|
||||
|
||||
describe "shop url" do
|
||||
it "shows the link to the shop if present" do
|
||||
SiteConfig.shop_url = "https://example.com"
|
||||
context "when rendering < 5 navigation links" do
|
||||
let!(:navigation_link_1) do
|
||||
create(:navigation_link,
|
||||
name: "Reading List",
|
||||
url: app_url("readinglist").to_s,
|
||||
icon: "<svg xmlns='http://www.w3.org/2000/svg'/></svg>",
|
||||
display_only_when_signed_in: false,
|
||||
position: 1)
|
||||
end
|
||||
let!(:navigation_link_2) do
|
||||
create(:navigation_link,
|
||||
name: "Podcasts",
|
||||
icon: "<svg xmlns='http://www.w3.org/2000/svg'/></svg>",
|
||||
display_only_when_signed_in: false,
|
||||
position: nil)
|
||||
end
|
||||
let!(:navigation_link_3) do
|
||||
create(:navigation_link,
|
||||
name: "Beauty",
|
||||
icon: "<svg xmlns='http://www.w3.org/2000/svg'/></svg>",
|
||||
display_only_when_signed_in: true,
|
||||
position: nil)
|
||||
end
|
||||
|
||||
before do
|
||||
visit "/"
|
||||
end
|
||||
|
||||
within("#main-nav-more") do
|
||||
expect(page).to have_link(href: SiteConfig.shop_url)
|
||||
it "shows the correct count of links" do
|
||||
within(".sidebar-navigation-links") do
|
||||
expect(page).to have_selector(".sidebar-navigation-link", count: 3)
|
||||
end
|
||||
end
|
||||
|
||||
it "does not show the shop if not present" do
|
||||
SiteConfig.shop_url = ""
|
||||
it "shows the correct navigation_links" do
|
||||
within(".sidebar-navigation-links") do
|
||||
expect(page).to have_text(navigation_link_1.name)
|
||||
expect(page).to have_text(navigation_link_2.name)
|
||||
expect(page).to have_text(navigation_link_3.name)
|
||||
end
|
||||
end
|
||||
|
||||
it "shows the correct urls" do
|
||||
within(".sidebar-navigation-links") do
|
||||
expect(page).to have_link(href: navigation_link_1.url)
|
||||
expect(page).to have_link(href: navigation_link_2.url)
|
||||
expect(page).to have_link(href: navigation_link_3.url)
|
||||
end
|
||||
end
|
||||
|
||||
it "shows the correct order of the links" do
|
||||
sidebar_navigation_link1 = page.find(".sidebar-navigation-link:nth-child(1)")
|
||||
expect(sidebar_navigation_link1).to have_text(navigation_link_1.name)
|
||||
|
||||
sidebar_navigation_link2 = page.find(".sidebar-navigation-link:nth-child(2)")
|
||||
expect(sidebar_navigation_link2).to have_text(navigation_link_3.name)
|
||||
|
||||
sidebar_navigation_link3 = page.find(".sidebar-navigation-link:nth-child(3)")
|
||||
expect(sidebar_navigation_link3).to have_text(navigation_link_2.name)
|
||||
end
|
||||
|
||||
it "shows the count when the url /readinglist is added" do
|
||||
within(".sidebar-navigation-link:nth-child(1)") do
|
||||
expect(page).to have_selector("#reading-list-count")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when rendering > 5 navigation links" do
|
||||
before do
|
||||
create_list(:navigation_link, 7)
|
||||
end
|
||||
|
||||
it "shows some in the 'More' section" do
|
||||
visit "/"
|
||||
|
||||
within("#main-nav-more") do
|
||||
expect(page).not_to have_text("Shop")
|
||||
expect(page).to have_selector(".sidebar-navigation-link", count: 2)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue