Skip to content

Commit

Permalink
Facets object
Browse files Browse the repository at this point in the history
  • Loading branch information
patanj101 committed Jun 7, 2024
1 parent cc6e131 commit e0705d7
Show file tree
Hide file tree
Showing 9 changed files with 159 additions and 144 deletions.
2 changes: 1 addition & 1 deletion app/assets/builds/tailwind.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion app/controllers/opportunities_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def load_opportunities
end

def opportunity_params
{}
params.permit(:employment, :location, :page, :posted, :role, :seniority)
end

# policy_scope(Job)
Expand Down
49 changes: 49 additions & 0 deletions app/models/facet.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# frozen_string_literal: true

class Facet
####
#### accessors
####

attr_accessor :attribute, :value, :position, :count, :url_params, :type

####
#### constants
####

####
#### extensions
####

include ActiveModel::Model

####
####
####

def active?(params)
'checked' if params[attribute].eql?(value)
end

def current_param = { attribute => value }

def public_attribute = attribute.titleize

def public_value = value.titleize

def presentation = "#{public_value.truncate(20)} (#{count})"

def url(params)
remove_filter_url = params.tap { |hs| hs.delete(attribute) }
apply_filter_url = params.merge(current_param)
active?(params) ? remove_filter_url : apply_filter_url
end

####
#### self
####

def self.set_attributes = @facets.map(&:attribute).uniq

# private
end
58 changes: 37 additions & 21 deletions app/tasks/opportunities_fetcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,31 +24,47 @@ def process
end

def plain_query
OpportunitiesQuery.call(@opportunities)
opportunities = OpportunitiesQuery.call(@opportunities)
apply_filters(opportunities)
end

# def plain_query
# filtered_jobs = JobFilter.new(@params, @opportunities).filter_and_sort
def apply_filters(opportunities)
filters = {
date_posted: filter_by_when_posted(@params[:posted]),
seniority: filter_by_seniority(@params[:seniority]),
locations: filter_by_location(@params[:location]),
roles: filter_by_role(@params[:role]),
employment_type: filter_by_employment(@params[:employment])
}.compact

# @jobs = filtered_jobs.eager_load(associated_tables)
# .order(sort_order(params[:sort]))
# # .page(params[:page])
# end
opportunities.where(filters)
end

def filter_by_when_posted(param)
return unless param.present?

number = Constants::DateConversion::CONVERT_TO_DAYS[param] || 99_999
number.days.ago..Date.today
end

# def associated_tables
# %i[requirement company locations countries]
# end
def filter_by_location(param)
return unless param.present?

# def sort_order(sort_param)
# sort_options = {
# 'title' => 'jobs.title ASC',
# 'title_desc' => 'jobs.title DESC',
# 'company' => 'companies.name ASC',
# 'company_desc' => 'companies.name DESC',
# 'created_at' => 'jobs.created_at DESC',
# 'created_at_asc' => 'jobs.created_at ASC'
# }.freeze
locations = param.split.map { |location| location.gsub('_', ' ').split.map(&:capitalize).join(' ') unless location == 'remote' }
{ city: locations }
end

# sort_options.fetch(sort_param, 'jobs.created_at DESC')
# end
def filter_by_role(param)
{ name: param.split } if param.present?
end

def filter_by_seniority(param)
return unless param.present?

param.split.map { |seniority| seniority.split('-').map(&:capitalize).join('-') }
end

def filter_by_employment(param)
param.split if param.present?
end
end
89 changes: 42 additions & 47 deletions app/tasks/opportunity_facets_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
class OpportunityFacetsBuilder < ApplicationTask
def initialize(opportunities, params)
@opportunities = opportunities
@params = params.to_h
@params = params
end

def call
Expand All @@ -22,77 +22,72 @@ def process
build_facets
end

###

def build_facets
@facets = {}
build_posted_array
build_seniority_array
build_location_array
build_role_array
build_employment_array
@facets
@facets = posted_facets
@facets += seniority_facets
@facets += location_facets
@facets += role_facets
@facets += employment_facets
sorted(@facets)
end

def build_posted_array
def posted_facets
attribute = 'posted'
date_cutoffs = Constants::DateConversion::CONVERT_TO_DAYS.transform_values { |v| v.days.ago.beginning_of_day }
results = date_cutoffs.map do |period, cutoff|
period_id = period.downcase.gsub(/last |within a /, '').gsub(' ', '-')
date_cutoffs.map do |period, cutoff|
value = period.downcase.gsub(/last |within a /, '').gsub(' ', '-')
count = @opportunities.where(date_posted: cutoff..Date.today).count
params = @params[:posted] ? @params[:posted].include?(period_id) : period == 'Any time'

['radio', period, period_id, count, params]
Facet.new(attribute:, value:, position: 0, count:, url_params: @params, type: 'radio')
end.compact
@facets['posted'] = results
end

def build_seniority_array
results = @opportunities.group(:seniority).count.map do |seniority, count|
def seniority_facets
attribute = 'seniority'
@opportunities.group(:seniority).count.map do |seniority, count|
next unless seniority

seniority_id = seniority.downcase.split.first
params = @params[:seniority]&.include?(seniority_id)

['checkbox', seniority, seniority_id, count, params]
value = seniority.downcase.split.first
Facet.new(attribute:, value:, position: 0, count:, url_params: @params, type: 'checkbox')
end.compact
@facets['seniority'] = sort_by_count_desc(results)
end

def build_location_array
results = @opportunities.group(:'locations.city').count.map do |location, count|
location_id = location ? location.downcase.gsub(' ', '_') : 'remote'
params = location ? @params[:location]&.include?(location_id) : @params[:location]&.include?('remote')
location ||= 'Remote'

['checkbox', location, location_id, count, params]
def location_facets
attribute = 'location'
@opportunities.group(:'locations.city').count.map do |location, count|
value = location ? location.downcase.gsub(' ', '_') : 'remote'
Facet.new(attribute:, value:, position: 0, count:, url_params: @params, type: 'checkbox')
end.compact
@facets['location'] = sort_by_count_desc(results)
end

def build_role_array
results = @opportunities.group(:'roles.name').count.map do |role, count|
def role_facets
attribute = 'role'
@opportunities.group(:'roles.name').count.map do |role, count|
next unless role

role_id = role
params = @params[:role]&.include?(role_id)
role = role.titleize

['checkbox', role, role_id, count, params]
value = role.downcase.split.first
Facet.new(attribute:, value:, position: 0, count:, url_params: @params, type: 'checkbox')
end.compact
@facets['role'] = sort_by_count_desc(results)
end

def build_employment_array
results = @opportunities.group(:employment_type).count.map do |employment, count|
def employment_facets
attribute = 'employment'
@opportunities.group(:employment_type).count.map do |employment, count|
next unless employment

employment_id = employment.downcase.gsub('-', '_')
params = @params[:employment]&.include?(employment_id)

['checkbox', employment, employment_id, count, params]
value = employment
Facet.new(attribute:, value:, position: 0, count:, url_params: @params, type: 'checkbox')
end.compact
@facets['employment'] = sort_by_count_desc(results)
end

def sort_by_count_desc(data)
data.sort_by { |item| -item[3] }
def sorted(facets)
facet_orders = %w[posted seniority location role employment]
sorted_by_count(facets)
facets.sort_by! { |facet| facet_orders.index(facet.attribute) }
end

def sorted_by_count(facets)
facets.sort_by! { |facet| facet.attribute.eql?('posted') ? 0 : -facet.count }
end
end
76 changes: 11 additions & 65 deletions app/views/shared/template/layout/_navigation.html.erb
Original file line number Diff line number Diff line change
@@ -1,78 +1,24 @@
<% nav_items = [
{ title: 'API', link_path: '#' },
{ title: 'Documentation', link_path: '#' },
{ title: 'Support', link_path: '#' }
] %>
<% nav_groups = [
{
title: 'Guides',
links: [
{ title: 'Introduction', link_path: root_path },
{ title: 'Quickstart', link_path: quick_start_index_path },
{ title: 'SDKs', link_path: sdks_path },
{ title: 'Authentication', link_path: authentication_index_path },
{ title: 'Pagination', link_path: pagination_index_path },
{ title: 'Errors', link_path: errors_path },
{ title: 'Webhooks', link_path: webhooks_path },
],
},
{
title: 'Resources',
links: [
{ title: 'Contacts', link_path: contacts_path },
{ title: 'Conversations', link_path: conversations_path },
{ title: 'Messages', link_path: messages_path },
{ title: 'Groups', link_path: groups_path },
{ title: 'Attachments', link_path: attachements_path },
],
}] %>
<% if false %>
<nav class="hidden lg:mt-10 lg:block" data-controller="side-nav">
<ul role="list">
<% nav_items.each do |item| %>
<li class="md:hidden">
<%= link_to item[:title], item[:link_path], class: 'block py-1 text-sm text-zinc-600 transition hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-white' %>
</li>
<% end %>
<% nav_groups.each do |group| %>
<%= render 'shared/template/layout/navigation_group_item', group: %>
<% end %>
<li class="sticky bottom-0 z-10 mt-6 min-[416px]:hidden">
<button type="button" href="#" class="w-full">
Sign in
</button>
</li>
</ul>
</nav>
<% end %>
<nav class="hidden lg:mt-10 lg:block" data-controller="side-nav">
<ul role="list">
<% @facets.each do |attribute, options| %>
<% @facets.group_by(&:attribute).each do |attribute, facets| %>
<li class="md:hidden">
<span class="block py-1 text-sm text-zinc-600 transition hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-white">
<%= attribute %>
<%= facets.first.public_attribute %>
</span>
</li>
<li class='relative mt-6'>
<h2
layout="position"
class="text-xs font-semibold text-zinc-900 dark:text-white"
>
<%= attribute %>
<h2 layout="position" class="text-xs font-semibold text-zinc-900 dark:text-white">
<%= facets.first.public_attribute %>
</h2>
<div class="relative mt-3 pl-2">
<div
layout
class="absolute inset-y-0 left-2 w-px bg-zinc-900/10 dark:bg-white/5"
></div>
<div layout class="absolute inset-y-0 left-2 bg-zinc-900/10 dark:bg-white/5"></div>
<ul role="list" class="border-l border-transparent" >
<% options.each do |option| %>
<%= render 'shared/template/layout/navigation_group_item', attribute:, option: %>
<% end %>
</ul>
</div>
</li>

<% facets.each do |facet| %>
<%= render "shared/template/layout/navigation_#{ facet.type }_item", facet: %>
<% end %>
</ul>
</div>
</li>
<% end %>
<li class="sticky bottom-0 z-10 mt-6 min-[416px]:hidden">
<button type="button" href="#" class="w-full">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<li class="relative" data-side-nav-target="link">
<div class="flex items-center">
<input id="<%= facet.value %>" name="<%= facet.attribute %>" type="checkbox" <%= facet.active?(request.params) %> class="h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600">
<%= link_to facet.url(request.params), class: 'flex justify-between gap-2 py-1 pr-3 text-sm transition pl-4 text-zinc-600 hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-white ' do %>
<span class="truncate"><%= facet.presentation %></span>
<% end %>
</div>
<ul role="list" class="hidden"></ul>
</li>

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<li class="relative" data-side-nav-target="link">
<div class="flex items-center">
<input id="<%= facet.value %>" name="<%= facet.attribute %>" type="radio" <%= facet.active?(request.params) %> class="h-4 w-4 border-gray-300 text-indigo-600 focus:ring-indigo-600"">
<%= link_to facet.url(request.params), class: 'flex justify-between gap-2 py-1 pr-3 text-sm transition pl-4 text-zinc-600 hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-white ' do %>
<span class="truncate"><%= facet.presentation %></span>
<% end %>
</div>
<ul role="list" class="hidden"></ul>
</li>

0 comments on commit e0705d7

Please sign in to comment.