Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
33a0050
scaffold new design route, controller, and view
MikeRose151 Aug 5, 2025
33308a9
implement blank table
MikeRose151 Aug 5, 2025
72d7c6d
start inserting data into table and refactor controller to support bo…
MikeRose151 Aug 6, 2025
007dbe1
add case contact data to table
MikeRose151 Aug 6, 2025
8b2fa24
add contact types data to table
MikeRose151 Aug 6, 2025
3cf13ba
add medium type data to table
MikeRose151 Aug 6, 2025
b6185bb
add created by data to table
MikeRose151 Aug 6, 2025
ddc50ca
add contacted data to table
MikeRose151 Aug 6, 2025
09475e3
add topics data to table
MikeRose151 Aug 6, 2025
a232762
add draft data to table
MikeRose151 Aug 6, 2025
706a1ea
remove sortability for a few rows
MikeRose151 Aug 8, 2025
32eb69d
run standardrb --fix
MikeRose151 Aug 11, 2025
6b080bb
fix more linting errors
MikeRose151 Aug 11, 2025
bdde5f4
add files to test exemption list (for timebeing)
MikeRose151 Aug 11, 2025
c6d4728
guard against nil errors
MikeRose151 Aug 12, 2025
cc1a8f4
fix date sorting so that it sorts the actual date and not the date st…
MikeRose151 Aug 13, 2025
f3e49aa
revert allow_skipping_tests file
MikeRose151 Aug 22, 2025
f7b0bd2
ci: retry
MikeRose151 Aug 22, 2025
7d23ef2
Update app/controllers/case_contacts/case_contacts_new_design_control…
compwron Sep 6, 2025
53a498a
Update app/controllers/concerns/loads_case_contacts.rb
compwron Sep 6, 2025
92635a8
add ending linebreak
MikeRose151 Sep 7, 2025
97b8597
remove repeated 'private'
MikeRose151 Sep 7, 2025
aa7ec6f
implement basic tests for case_contacts_new_design
MikeRose151 Sep 7, 2025
f90061a
perform linting
MikeRose151 Sep 7, 2025
593c1a7
relocate test file
MikeRose151 Sep 7, 2025
6531d8d
add smoke spec for LoadCaseContacts concern
MikeRose151 Sep 7, 2025
c5d1e2d
chore(ci): retrigger
MikeRose151 Sep 7, 2025
eed8539
chore(ci): retrigger
MikeRose151 Sep 7, 2025
0d4aeef
chore(ci): retrigger
MikeRose151 Sep 7, 2025
3dc8f06
adjust code climate test reporter download
MikeRose151 Sep 7, 2025
31027c1
fix attempt for code climate test reporter download
MikeRose151 Sep 7, 2025
81aaf4b
revert rspec workflow
MikeRose151 Sep 7, 2025
5fededf
remove code climate from CI
MikeRose151 Sep 13, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 1 addition & 6 deletions .github/workflows/rspec.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,20 +68,15 @@ jobs:
bundle exec rake db:schema:load
bundle exec rails assets:precompile

- name: Run rspec and upload code coverage
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no more code coverage? I mean it does speed it up, but was this intended?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah I thought what I've done here is removing what we're doing with code climate, as per this slack thread: https://rubyforgood.slack.com/archives/CVB0QJGVD/p1757473365867509?thread_ts=1757356417.512309&cid=CVB0QJGVD

have I removed more than I was supposed to? 🫣

- name: Run rspec
env:
DATABASE_HOST: localhost
POSTGRES_USER: postgres
CASA_DATABASE_PASSWORD: password
POSTGRES_HOST_AUTH_METHOD: trust
RUN_SIMPLECOV: true
CC_TEST_REPORTER_ID: 31464536e34ab26588cb951d0fa6b5898abdf401dbe912fd47274df298e432ac
run: |
curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
chmod +x ./cc-test-reporter
./cc-test-reporter before-build
RUBYOPT='-W:no-deprecated -W:no-experimental' bundle exec rspec
./cc-test-reporter after-build --exit-code $?

- name: Archive selenium screenshots
if: ${{ failure() }}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
class CaseContacts::CaseContactsNewDesignController < ApplicationController
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will want to rename this someday :)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed :) the thinking was that this change would be a gradual roll out / feature flag, so have just gone with this name for the time being

include LoadsCaseContacts

def index
load_case_contacts
end

def datatable
authorize CaseContact
case_contacts = policy_scope(current_organization.case_contacts)
datatable = CaseContactDatatable.new case_contacts, params

render json: datatable
end
end
39 changes: 3 additions & 36 deletions app/controllers/case_contacts_controller.rb
Original file line number Diff line number Diff line change
@@ -1,30 +1,15 @@
# frozen_string_literal: true

class CaseContactsController < ApplicationController
include LoadsCaseContacts

before_action :set_case_contact, only: %i[edit destroy]
before_action :set_contact_types, only: %i[new edit create]
before_action :require_organization!
after_action :verify_authorized, except: %i[leave]

def index
authorize CaseContact

@current_organization_groups = current_organization_groups

@filterrific = initialize_filterrific(
all_case_contacts,
params[:filterrific],
select_options: {
sorted_by: CaseContact.options_for_sorted_by
}
) || return

@pagy, @filtered_case_contacts = pagy(@filterrific.find)
case_contacts = CaseContact.case_hash_from_cases(@filtered_case_contacts)
case_contacts = case_contacts.select { |k, _v| current_user.casa_cases.pluck(:id).include?(k) } if current_user.volunteer?
case_contacts = case_contacts.select { |k, _v| k == params[:casa_case_id].to_i } if params[:casa_case_id].present?

@presenter = CaseContactPresenter.new(case_contacts)
load_case_contacts
end

def drafts
Expand Down Expand Up @@ -96,24 +81,6 @@ def set_contact_types
@contact_types = ContactType.for_organization(current_organization)
end

def current_organization_groups
current_organization.contact_type_groups
.includes(:contact_types)
.joins(:contact_types)
.where(contact_types: {active: true})
.uniq
end

def all_case_contacts
policy_scope(current_organization.case_contacts).preload(
:creator,
:followups,
contact_types: :contact_type_group,
contact_topic_answers: :contact_topic,
casa_case: :volunteers
)
end

def additional_expense_params
@additional_expense_params ||= AdditionalExpenseParamsService.new(params).calculate
end
Expand Down
44 changes: 44 additions & 0 deletions app/controllers/concerns/loads_case_contacts.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
module LoadsCaseContacts
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice reuse :)

extend ActiveSupport::Concern

private

def load_case_contacts
authorize CaseContact

@current_organization_groups = current_organization_groups

@filterrific = initialize_filterrific(
all_case_contacts,
params[:filterrific],
select_options: {
sorted_by: CaseContact.options_for_sorted_by
}
) || return

@pagy, @filtered_case_contacts = pagy(@filterrific.find)
case_contacts = CaseContact.case_hash_from_cases(@filtered_case_contacts)
case_contacts = case_contacts.slice(*current_user.casa_cases.pluck(:id)) if current_user.volunteer?
case_contacts = case_contacts.select { |k, _v| k == params[:casa_case_id].to_i } if params[:casa_case_id].present?

@presenter = CaseContactPresenter.new(case_contacts)
end

def current_organization_groups
current_organization.contact_type_groups
.includes(:contact_types)
.joins(:contact_types)
.where(contact_types: {active: true})
.uniq
end

def all_case_contacts
policy_scope(current_organization.case_contacts).preload(
:creator,
:followups,
contact_types: :contact_type_group,
contact_topic_answers: :contact_topic,
casa_case: :volunteers
)
end
end
8 changes: 8 additions & 0 deletions app/decorators/case_contact_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@ def contact_types
end
end

def contact_types_comma_separated
if object.contact_types.any?
object.contact_types&.map { |ct| ct.name }&.join(", ")
else
"No contact type specified"
end
end

def report_contact_types
object.contact_types&.map { |ct| ct.name }&.join("|")
end
Expand Down
6 changes: 5 additions & 1 deletion app/javascript/src/dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ const defineCaseContactsTable = function () {
{
scrollX: true,
searching: false,
order: [[0, 'desc']]
order: [[2, 'desc']],
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will this affect existing functionality in addition to new functionality?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it will affect existing functionality, as there isn't an existing case contacts table. Sorry it's been a few weeks since I was deeper into this but I believe that code block was left in from a similar table that used to exist. That old table can be seen in this PR: #1113, which is also the PR that this code block was added

columnDefs: [
{ type: 'date', targets: 2 },
{ orderable: false, targets: [0, 1, -1] } // disable sort on bell, chevron, vertical elipses menu
]
}
)
}
Expand Down
98 changes: 98 additions & 0 deletions app/views/case_contacts/case_contacts_new_design/index.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<div class="title-wrapper pt-30">
<div class="row align-items-center">
<div class="title mb-30">
<h1>Case Contacts</h1>
</div>
</div>
</div>

<div class="card-style mb-30">
<div class="table-wrapper">
<table
id="case_contacts"
class="table"
data-source="<%= datatable_case_contacts_path format: :json %>">
<thead>
<tr>
<th data-orderable="false"></th>
<th data-orderable="false"></th>
<th><h6>Date</h6></th>
<th><h6>Case</h6></th>
<th><h6>Relationship</h6></th>
<th><h6>Medium</h6></th>
<th><h6>Created By</h6></th>
<th><h6>Contacted</h6></th>
<th><h6>Topics</h6></th>
<th><h6>Draft</h6></th>
<th data-orderable="false"></th>
</tr>
<!-- end table row-->
</thead>
<tbody>
<% @presenter.case_contacts.each do |casa_case_id, case_contacts| %>
<% case_contacts.each do |case_contact| %>
<tr data-testid="case_contact-row">
<td>
<i class='fas fa-bell'></i>
</td>
<td>
<i class="fa-solid fa-chevron-down"></i>
</td>
<td>
<%= I18n.l(case_contact[:occurred_at], format: :full) if case_contact[:occurred_at].present? %>
</td>
<td>
<%= @presenter.display_case_number(casa_case_id) %>
</td>
<td>
<%= case_contact.decorate.contact_types_comma_separated %>
</td>
<td>
<%= case_contact.medium_type&.capitalize %>
</td>
<td>
<% if policy(case_contact).edit? %>
<% if current_user.volunteer? %>
<%= case_contact.creator&.display_name %>
<% else %>
<% if case_contact.creator&.supervisor? %>
<%= link_to case_contact.creator&.display_name, edit_supervisor_path(case_contact.creator), data: { turbo: false } %>
<% elsif case_contact.creator&.casa_admin? %>
<%= link_to case_contact.creator&.display_name, edit_users_path, data: { turbo: false } %>
<% else %>
<%= link_to case_contact.creator&.display_name, edit_volunteer_path(case_contact.creator), data: { turbo: false } %>
<% end %>
<% end %>
<% else %>
<%= case_contact.creator&.display_name %>
<% end %>
</td>
<td>
<% if case_contact.contact_made %>
<i class="lni lni-checkmark-circle" style="color: green;"></i>
Copy link

Copilot AI Sep 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inline styles should be avoided in favor of CSS classes. Consider defining a CSS class for the green checkmark styling.

Copilot uses AI. Check for mistakes.
<% else %>
<i class="lni lni-cross-circle" style="color: orange;"></i>
Copy link

Copilot AI Sep 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inline styles should be avoided in favor of CSS classes. Consider defining a CSS class for the orange cross styling.

Copilot uses AI. Check for mistakes.
<% end %>
<%= "(#{"%02d:%02d" % [case_contact.duration_minutes / 60, case_contact.duration_minutes % 60]})" if case_contact.duration_minutes %>
</td>
<td>
<%= case_contact.contact_topics.map(&:question).join(" | ") %>
</td>
<td>
<% if !case_contact.active? %>
<span class="badge badge-pill light-bg text-black" data-testid="draft-badge">
Draft
</span>
<% end %>
</td>
<td>
<i class="fas fa-ellipsis-v"></i>
</td>
</tr>
<% end %>
<% end %>
</tbody>
</table>
<!-- end table -->
</div>
</div>
3 changes: 2 additions & 1 deletion config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@

get "case_contacts/leave", to: "case_contacts#leave", as: "leave_case_contacts_form"
get "case_contacts/drafts", to: "case_contacts#drafts"
resources :case_contacts, except: %i[create update show] do
get "case_contacts/new_design", to: "case_contacts/case_contacts_new_design#index"
resources :case_contacts, except: %i[create update show], concerns: %i[with_datatable] do
member do
post :restore
end
Expand Down
15 changes: 15 additions & 0 deletions spec/controllers/concerns/loads_case_contacts_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
require "rails_helper"

RSpec.describe LoadsCaseContacts do
let(:host) do
Class.new do
include LoadsCaseContacts
end
end

it "exists and defines private API" do
expect(described_class).to be_a(Module)
expect(host.private_instance_methods)
.to include(:load_case_contacts, :current_organization_groups, :all_case_contacts)
end
end
43 changes: 43 additions & 0 deletions spec/requests/case_contacts/case_contacts_new_design_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
require "rails_helper"

RSpec.describe "/case_contacts_new_design", type: :request do
let(:organization) { create(:casa_org) }
let(:admin) { create(:casa_admin, casa_org: organization) }

before { sign_in admin }

describe "GET /index" do
subject(:request) do
get case_contacts_new_design_path

response
end

let!(:casa_case) { create(:casa_case, casa_org: organization) }
let!(:past_contact) { create(:case_contact, :active, casa_case: casa_case, occurred_at: 3.weeks.ago) }
let!(:recent_contact) { create(:case_contact, :active, casa_case: casa_case, occurred_at: 3.days.ago) }
let!(:draft_contact) { create(:case_contact, casa_case: casa_case, occurred_at: 5.days.ago, status: "started") }

it { is_expected.to have_http_status(:success) }

it "lists exactly two active contacts and one draft" do
doc = Nokogiri::HTML(request.body)
case_contact_rows = doc.css('[data-testid="case_contact-row"]')
expect(case_contact_rows.size).to eq(3)
end

it "shows the draft badge exactly once" do
doc = Nokogiri::HTML(request.body)
expect(doc.css('[data-testid="draft-badge"]').count).to eq(1)
end

it "orders contacts by occurred_at desc" do
body = request.body

recent_index = body.index(I18n.l(recent_contact.occurred_at, format: :full))
past_index = body.index(I18n.l(past_contact.occurred_at, format: :full))

expect(recent_index).to be < past_index
end
end
end