Skip to content

Commit

Permalink
Add team assignments module (#4675)
Browse files Browse the repository at this point in the history
Co-authored-by: Tim O'Farrell <[email protected]>
  • Loading branch information
embarnard and tofarr authored Aug 16, 2024
1 parent 4176652 commit 9422238
Show file tree
Hide file tree
Showing 13 changed files with 286 additions and 6 deletions.
20 changes: 20 additions & 0 deletions app/assets/stylesheets/pages/dashboard.scss
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
display: flex;
justify-content: flex-end;
gap: 2rem;
align-items: center;

p {
color: $color-grey-medium;
Expand Down Expand Up @@ -122,6 +123,25 @@
}
}

.team-assignments {
.pagination > a,
.pagination em.current,
.pagination > span {
display: none;
border: none;
}

.pagination a.previous_page,
.pagination a.next_page {
display: inline;
}

.user-count{
color: $color-grey-medium;
}
}


.returns-by-status {

.counts {
Expand Down
3 changes: 2 additions & 1 deletion app/controllers/hub/dashboard_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ def presenter
current_user,
current_ability,
"#{params[:type]}/#{params[:id]}",
params[:stage]
params[:stage],
(params[:page] || 1)
)
end

Expand Down
42 changes: 42 additions & 0 deletions app/helpers/will_paginate_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
require 'will_paginate/view_helpers/action_view'

module WillPaginateHelper
class WillPaginateJSLinkRenderer < WillPaginate::ActionView::LinkRenderer
def prepare(collection, options, template)
options[:params] ||= {}
options[:params]['_'] = nil
super(collection, options, template)
end

protected

def url(page)
@base_url_params ||= begin
url_params = merge_get_params(default_url_params)
url_params[:only_path] = true
url_params[:action] = @options[:action]
merge_optional_params(url_params)
end

url_params = @base_url_params.dup
add_current_page_param(url_params, page)

@template.url_for(url_params)
end

def link(text, target, attributes = {})
if target.is_a? Integer
attributes[:rel] = rel_value(target)
target = url(target)
end

@template.link_to(target, attributes.merge(remote: true)) do
text.to_s.html_safe
end
end
end

def js_will_paginate(collection, options = {})
will_paginate(collection, options.merge(:renderer => WillPaginateHelper::WillPaginateJSLinkRenderer))
end
end
7 changes: 6 additions & 1 deletion app/presenters/hub/dashboard/dashboard_presenter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ class DashboardPresenter
attr_reader :selected_value
DashboardFilterOption = Struct.new(:value, :model, :children, :has_parent)

def initialize(current_user, current_ability, selected_value, return_summary_stage=nil)
def initialize(current_user, current_ability, selected_value, return_summary_stage = nil, page = 1)
@current_user = current_user
@current_ability = current_ability
@selected_value = selected_value
@return_summary_stage = return_summary_stage
@page = page
end

def clients
Expand Down Expand Up @@ -67,6 +68,10 @@ def service_level_agreements_notifications_presenter
)
end

def team_assignment_presenter
@team_assignment_presenter ||= Hub::Dashboard::TeamAssignmentPresenter.new(@current_user, @page, selected_model)
end

private

def self.flatten_filter_options(filter_options, result)
Expand Down
49 changes: 49 additions & 0 deletions app/presenters/hub/dashboard/team_assignment_presenter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
module Hub
module Dashboard
class TeamAssignmentPresenter
attr_reader :page, :user_count

def initialize(current_user, page, selected_model)
@current_user = current_user
@page = page
@selected_model = selected_model
end

def team_assignment_users
return nil unless @current_user.org_lead? || @current_user.site_coordinator? || @current_user.coalition_lead?

accessible_users_by_role = if @current_user.coalition_lead?
return nil if @selected_model.instance_of?(Coalition)

organizations = @selected_model.instance_of?(Organization) ? @selected_model : @current_user.role.coalition.organizations
sites = VitaPartner.sites.where(parent_organization: organizations)
roles = OrganizationLeadRole.where(organization: organizations) + SiteCoordinatorRole.assignable_to_sites(sites) + TeamMemberRole.assignable_to_sites(sites)
User.where(role: roles)
elsif @current_user.org_lead?
organization = @current_user.role.organization
sites = @selected_model.instance_of?(Site) ? @selected_model : VitaPartner.sites.where(parent_organization: organization)
roles = OrganizationLeadRole.where(organization: organization) + SiteCoordinatorRole.assignable_to_sites(sites) + TeamMemberRole.assignable_to_sites(sites)
User.where(role: roles)
elsif @current_user.site_coordinator?
sites = @selected_model.instance_of?(Site) ? @selected_model : @current_user.role.sites
roles = SiteCoordinatorRole.assignable_to_sites(sites) + TeamMemberRole.assignable_to_sites(sites)
User.where(role: roles)
end

@user_count = accessible_users_by_role.count

accessible_users_by_role.paginate(page: @page, per_page: 5)
end

def ordered_by_tr_count_users
return unless team_assignment_users.present?

team_assignment_users.select('users.*, COUNT(tax_returns.id) AS tax_returns_count')
.left_joins(:assigned_tax_returns)
.group('users.id, users.name, users.role_type')
.order('tax_returns_count DESC')
end

end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
<% if p.flagged_clients.exists? %>
<div class="paging">
<p><%= p.flagged_clients.limit(3).count %> of <%= p.flagged_clients.count %></p>
<%= link_to t("hub.dashboard.show.view_all"), hub_clients_path(flagged: true), class: "text--centered" %>
<p> <%= link_to t("hub.dashboard.show.view_all"), hub_clients_path(flagged: true), class: "text--centered" %></p>
</div>
<% else %>
<p><%= t("hub.dashboard.show.action_required.no_clients") %></p>
Expand Down
5 changes: 2 additions & 3 deletions app/views/hub/dashboard/_team_assignment.html.erb
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
<div class="card">
<h2>Team Assignment</h2>
<p>TODO: Implement</p>
<div class="card dashboard-table team-assignments">
<%= render "hub/dashboard/team_assignment_content" %>
</div>
61 changes: 61 additions & 0 deletions app/views/hub/dashboard/_team_assignment_content.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<% p = presenter.team_assignment_presenter %>
<% users = p.team_assignment_users %>
<% ordered_users = p.ordered_by_tr_count_users %>
<h2><%= t("hub.dashboard.show.team_assignment.title") %></h2>

<table>
<thead>
<tr>
<th><%= t("hub.dashboard.show.team_assignment.name") %></th>
<th><%= t("hub.dashboard.show.team_assignment.role") %></th>
<th><%= t("hub.dashboard.show.team_assignment.assigned_returns") %></th>
</tr>
</thead>
<tbody>
<% if ordered_users&.present? %>
<% ordered_users.each do |user| %>
<tr>
<td>
<%= user.name %>
</td>
<td>
<%=
case user.role_type
when SiteCoordinatorRole::TYPE
t("general.site_coordinator")
when OrganizationLeadRole::TYPE
t("general.organization_lead")
when TeamMemberRole::TYPE
t("general.team_member")
else
""
end
%>
</td>
<td>
<%= link_to user.assigned_tax_returns.count, hub_clients_path(assigned_user_id: user.id) %>
</td>
</tr>
<% end %>
<% end %>
</tbody>
</table>

<% if users.present? %>
<div class="paging">
<div class="user-count">
<% start_user = ((p.page.to_i - 1) * 5) + 1 %>
<% end_user = [start_user + 4, p.user_count].min %>
<%= t("hub.dashboard.show.team_assignment.pager", start_range: start_user, end_range: end_user, total: p.user_count) %>
</div>
<div><%= js_will_paginate users,
previous_label: "<i class='icon icon-keyboard_arrow_left'></i><span class='hide-on-mobile'>Previous 5</span>",
next_label: "<span class='hide-on-mobile'>Next 5</span><i class='icon icon-keyboard_arrow_right'></i>",
inner_window: 0,
outer_window: 0,
action: :team_assignment
%></div>
</div>
<% else %>
<p><%= t("hub.dashboard.show.team_assignment.no_team_assignments") %></p>
<% end %>
3 changes: 3 additions & 0 deletions app/views/hub/dashboard/team_assignment.js.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
$(".team-assignments").fadeOut('fast', function(){
$(this).html("<%= escape_javascript render "hub/dashboard/team_assignment_content" %>").fadeIn('fast')
})
7 changes: 7 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -984,6 +984,13 @@ en:
title: Resources
returns_by_status: Returns by Status
sla_title: Service Level Agreements Notifications
team_assignment:
assigned_returns: Assigned Returns
name: Name
no_team_assignments: No Team Assignments to display at the moment
pager: Displaying %{start_range} - %{end_range} of %{total}
role: Role
title: Team Assignment
title: Dashboard
total_number_of_returns: Total number of returns
total_returns_in_html: Total Returns in [<strong>%{stage}</strong>]
Expand Down
7 changes: 7 additions & 0 deletions config/locales/es.yml
Original file line number Diff line number Diff line change
Expand Up @@ -993,6 +993,13 @@ es:
title: Recursos
returns_by_status: Devoluciones por estado
sla_title: Notificaciones de acuerdos de nivel de servicio
team_assignment:
assigned_returns: Devoluciones asignadas
name: Nombre
no_team_assignments: No hay asignaciones de equipo para mostrar en este momento
pager: Mostrando %{start_range} - %{end_range} de %{total}
role: Role
title: Asignación de equipo
title: Panel
total_number_of_returns: Número total de devoluciones
total_returns_in_html: Rentabilidad total en [<strong>%{stage}</strong>]
Expand Down
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,7 @@ def scoped_navigation_routes(context, navigation)
resources :dashboard, only: [:index] do
get "/:type/:id", to: "dashboard#show", on: :collection, as: :show
get "/:type/:id/returns-by-status", to: "dashboard#returns_by_status", on: :collection, as: :returns_by_status
get "/:type/:id/team-assignment", to: "dashboard#team_assignment", on: :collection, as: :team_assignment
end

resources :tax_return_selections, path: "tax-return-selections", only: [:create, :show, :new]
Expand Down
85 changes: 85 additions & 0 deletions spec/presenters/hub/team_assignment_presenter_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
require "rails_helper"

describe Hub::Dashboard::TeamAssignmentPresenter do
# Users
let!(:org_lead) { create :organization_lead_user, organization: oregano_org }
let!(:other_org_lead) { create :organization_lead_user, organization: other_org }
let!(:site_coordinator) { create :site_coordinator_user, role: create(:site_coordinator_role, sites: [site, other_site]) }
let!(:other_site_coordinator) { create :site_coordinator_user, role: create(:site_coordinator_role, sites: [other_org_child_site]) }
let!(:coalition_lead) { create :coalition_lead_user, coalition: create(:coalition) }
let!(:team_member) { create :user, role: (create :team_member_role, sites: [site]) }
let!(:other_team_member) { create :user, role: (create :team_member_role, sites: [other_site]) }
let!(:inaccessible_team_member) { create :user, role: (create :team_member_role, sites: [create(:site)]) }

# Vita Partners
let(:oregano_org) { create :organization, name: "Oregano Org", coalition: coalition_lead.role.coalition }
let(:other_org) { create :organization, name: "Other Org", coalition: coalition_lead.role.coalition }
let(:site) { create :site, parent_organization: oregano_org }
let(:other_site) { create :site, parent_organization: oregano_org }
let(:other_org_child_site) { create :site, parent_organization: other_org }

# Params
let(:selected_model) { oregano_org }
let(:page) { 1 }

# Tax Returns
let!(:assigned_tax_return_1) { create :gyr_tax_return, assigned_user: site_coordinator }
let!(:assigned_tax_return_2) { create :gyr_tax_return, assigned_user: site_coordinator }
let!(:assigned_tax_return_3) { create :gyr_tax_return, assigned_user: team_member }

context "as a coalition lead" do
subject { described_class.new(coalition_lead, page, selected_model) }

context "when selecting a coalition" do
let(:selected_model) { coalition_lead.role.coalition }

it "returns no users" do
expect(subject.ordered_by_tr_count_users).to eq nil
end
end

context "when selecting an org" do
it "shows org leads, team members and site coordinators belonging to selected org or child sites and their number of assigned tax returns in desc order" do
expect(subject.ordered_by_tr_count_users).to eq [site_coordinator, team_member, org_lead, other_team_member]
end
end

context "when selecting another org" do
let(:selected_model) { other_org }

it "doesn't show users from the other org" do
expect(subject.ordered_by_tr_count_users).to eq [other_org_lead, other_site_coordinator]
end
end
end

context "as an org lead" do
subject { described_class.new(org_lead, page, selected_model) }

context "when selecting an organization in the drop down" do
it "shows team members, org leads, site coordinators under that selected org or its child sites and their number of assigned tax returns in desc order" do
expect(subject.ordered_by_tr_count_users).to eq [site_coordinator, team_member, org_lead, other_team_member]
end
end

context "when selecting a site" do
let(:selected_model) { site }

it "shows team members, org leads, site coordinators under that site or with its parent org" do
expect(subject.ordered_by_tr_count_users).to eq [site_coordinator, team_member, org_lead]
end
end
end

context "as an site coordinator" do
subject { described_class.new(site_coordinator, page, selected_model) }

context "when selecting a site" do
let(:selected_model) { site }

it "Site coordinators and team members that are assigned to selected site" do
expect(subject.ordered_by_tr_count_users).to eq [site_coordinator, team_member]
end
end
end
end

0 comments on commit 9422238

Please sign in to comment.