Skip to content

Commit

Permalink
Co-authored-by: Eric Halverson <[email protected]>
Browse files Browse the repository at this point in the history
Co-authored-by: James Garcia <[email protected]>
add datatable checkboxes to volunteer#index view for bulk assignment

add system test for volunteers/index
  • Loading branch information
ShamiTomita authored and github username committed Oct 17, 2023
1 parent 7cae9aa commit 9f6b4b3
Show file tree
Hide file tree
Showing 18 changed files with 918 additions and 31 deletions.
503 changes: 503 additions & 0 deletions 3

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions app/assets/stylesheets/application.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
);
@use "bootstrap-datepicker/dist/css/bootstrap-datepicker";
@use "datatables.net-dt/css/jquery.dataTables";
@use "jquery-datatables-checkboxes/css/dataTables.checkboxes";
@use "@fortawesome/fontawesome-free/scss/fontawesome";
@use "@fortawesome/fontawesome-free/scss/solid";
@use "select2/dist/css/select2";
Expand Down
13 changes: 13 additions & 0 deletions app/assets/stylesheets/pages/volunteers.scss
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,16 @@ body.volunteers {
}
}
}


table#volunteers.dataTable.hover tbody tr.selected > * {
background-color: rgba(54, 92, 245, 0.1);
box-shadow: none;
color: inherit;
}

table#volunteers.dataTable.hover > tbody > tr.selected:hover > * {
background-color: rgba(54, 92, 245, 0.15);
box-shadow: none !important;
color: inherit;
}
23 changes: 23 additions & 0 deletions app/assets/stylesheets/shared/header.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
@use "../base/breakpoints.scss" as screen-sizes;

.header {
.header-left {
.menu-toggle-btn {
display: none;

.main-btn {
border-radius: 4px !important;
}
}
}
}

@media only screen and (max-width: screen-sizes.$mobile) {
.header {
.header-left {
.menu-toggle-btn {
display: block;
}
}
}
}
56 changes: 55 additions & 1 deletion app/controllers/supervisor_volunteers_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,67 @@ def unassign
redirect_to request.referer, notice: flash_message
end

def bulk_assignment
authorize :supervisor_volunteer
if mass_assign_volunteers?
volunteer_ids = supervisor_volunteer_params[:volunteer_ids]
supervisor = supervisor_volunteer_params[:supervisor_id]
vol = "Volunteer".pluralize(volunteer_ids.length)

if supervisor == "unassign"
name_array = bulk_unassign!(volunteer_ids)
flash_message = "#{vol} #{name_array.to_sentence} successfully unassigned"
else
supervisor = supervisor_volunteer_parent
name_array = bulk_assign!(supervisor, volunteer_ids)
flash_message = "#{vol} #{name_array.to_sentence} successfully reassigned to #{supervisor.display_name}"
end

redirect_to volunteers_path, notice: flash_message
else
redirect_to volunteers_path, notice: "Please select at least one volunteer and one supervisor."
end
end

private

def supervisor_volunteer_params
params.require(:supervisor_volunteer).permit(:supervisor_id, :volunteer_id)
params.require(:supervisor_volunteer).permit(:supervisor_id, :volunteer_id, volunteer_ids: [])
end

def supervisor_volunteer_parent
Supervisor.find(params[:supervisor_id] || supervisor_volunteer_params[:supervisor_id])
end

def mass_assign_volunteers?
supervisor_volunteer_params[:volunteer_ids] && supervisor_volunteer_params[:supervisor_id] ? true : false
end

def bulk_assign!(supervisor, volunteer_ids)
created_volunteers = []
volunteer_ids.each do |vol_id|
if (supervisor_volunteer = SupervisorVolunteer.find_by(volunteer_id: vol_id.to_i))
supervisor_volunteer.update!(supervisor_id: supervisor.id)
else
supervisor_volunteer = supervisor.supervisor_volunteers.create(volunteer_id: vol_id.to_i)
end
supervisor_volunteer.is_active = true
volunteer = supervisor_volunteer.volunteer
supervisor_volunteer.save
created_volunteers << volunteer.display_name.to_s
end
created_volunteers
end

def bulk_unassign!(volunteer_ids)
unassigned_volunteers = []
volunteer_ids.each do |vol_id|
supervisor_volunteer = SupervisorVolunteer.find_by(volunteer_id: vol_id.to_i)
supervisor_volunteer.update(is_active: false)
volunteer = supervisor_volunteer.volunteer
supervisor_volunteer.save
unassigned_volunteers << volunteer.display_name.to_s # take into account single assignments and give multiple assignments proper format
end
unassigned_volunteers
end
end
1 change: 1 addition & 0 deletions app/controllers/volunteers_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class VolunteersController < ApplicationController

def index
authorize Volunteer
@supervisors = policy_scope(current_organization.supervisors)
end

def show
Expand Down
2 changes: 2 additions & 0 deletions app/javascript/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import 'trix'
import '@rails/actiontext'

require('datatables.net-dt')(null, window.jQuery) // First parameter is the global object. Defaults to window if null
require('datatables.net-select')(null, window.jQuery)
require('jquery-datatables-checkboxes')(null, window.jQuery)
require('select2')(window.jQuery)
require('@rails/ujs').start()
require('@rails/activestorage').start()
Expand Down
38 changes: 37 additions & 1 deletion app/javascript/src/dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,21 @@ $(() => { // JQuery's callback for the DOM loading
}
})
},
order: [[6, 'desc']],
order: [[7, 'desc']],
select: {
style: 'multi'
},
columns: [
{
data: 'id',
targets: 0,
searchable: false,
orderable: false,
checkboxes: {
selectRow: true,
stateSave: false
}
},
{
name: 'display_name',
render: (data, type, row, meta) => {
Expand Down Expand Up @@ -293,6 +306,29 @@ $(() => { // JQuery's callback for the DOM loading
}
})

$('#form-bulk-assignment').on('submit', function (e) {
const form = this
const rowsSelected = volunteersTable.column(0).checkboxes.selected()

$.each(rowsSelected, function (index, rowId) {
$(form).append(
$('<input>')
.attr('type', 'hidden')
.attr('name', 'supervisor_volunteer[volunteer_ids][]')
.val(rowId)
)
})
})

volunteersTable.column(0).on('change', function () {
const rowsSelected = volunteersTable.column(0).checkboxes.selected()
if (rowsSelected.count() === 0) {
$('#volunteers-selected').html('')
} else {
$('#volunteers-selected').html('s (' + rowsSelected.count() + ')')
}
})

// Because the table saves state, we have to check/uncheck modal inputs based on what
// columns are visible
volunteersTable.columns().every(function (index) {
Expand Down
2 changes: 2 additions & 0 deletions app/models/volunteer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
class Volunteer < User
devise :invitable, invite_for: 1.year

BULK_COLUMN = "bulk"
NAME_COLUMN = "name"
EMAIL_COLUMN = "email"
SUPERVISOR_COLUMN = "supervisor"
Expand All @@ -16,6 +17,7 @@ class Volunteer < User
EXTRA_LANGUAGES_COLUMN = "has_any_extra_languages"
ACTIONS_COLUMN = "actions"
TABLE_COLUMNS = [
BULK_COLUMN,
NAME_COLUMN,
EMAIL_COLUMN,
SUPERVISOR_COLUMN,
Expand Down
4 changes: 4 additions & 0 deletions app/policies/supervisor_volunteer_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,8 @@ def create?
def unassign?
user.casa_admin? || user.supervisor?
end

def bulk_assignment?
user.casa_admin? || user.supervisor?
end
end
6 changes: 1 addition & 5 deletions app/views/supervisors/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -129,18 +129,14 @@
<table id="active_volunteers" class="table">
<thead>
<tr>
<th></th>
<th><h6>Active volunteers not assigned to supervisors</h6></th>
<th><h6>Assigned to Case(s)</h6></th>
</tr>
<!-- end table row-->
</thead>
<tbody>
<% @available_volunteers.each_with_index do |volunteer, index| %>
<% @available_volunteers.each do |volunteer| %>
<tr>
<td>
<%= index + 1 %>
</td>
<td>
<%= link_to volunteer.display_name, edit_volunteer_path(volunteer) %>
</td>
Expand Down
102 changes: 79 additions & 23 deletions app/views/volunteers/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -161,32 +161,88 @@
<div class="row">
<div class="col-lg-12">
<div class="card-style mb-30">
<h6 class="mb-10">Responsive Data Table</h6>
<span class="mb-3">
<button type="button" class="main-btn dark-btn btn-sm mb-2 mb-md-0" data-bs-toggle="modal" data-bs-target="#bulk-assigment-modal">
<i class="lni lni-users mr-10"></i>
Manage Volunteer<span class="d-inline" id="volunteers-selected"></span>
</button>
</span>
<div class="table-responsive">
<table
class="table"
id="volunteers"
data-source="<%= datatable_volunteers_path format: :json %>">
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Supervisor</th>
<th>Status</th>
<th>Assigned To Transition Aged Youth</th>
<th>Case Number(s)</th>
<th>Last Attempted Contact</th>
<th>Contacts Made in Past 60 Days</th>
<th>Hours spent in last 30 days</th>
<th>Extra Languages</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<%= form_with(url: bulk_assignment_supervisor_volunteers_path, id: "form-bulk-assignment") do |form| %>
<table
class="table hover"
id="volunteers"
data-source="<%= datatable_volunteers_path format: :json %>">
<thead>
<tr>
<th></th>
<th>Name</th>
<th>Email</th>
<th>Supervisor</th>
<th>Status</th>
<th>Assigned To Transition Aged Youth</th>
<th>Case Number(s)</th>
<th>Last Attempted Contact</th>
<th>Contacts Made in Past 60 Days</th>
<th>Hours spent in last 30 days</th>
<th>Extra Languages</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
</tbody>
</table>

<div class="warning-modal">
<div class="modal fade" id="bulk-assigment-modal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content card-style">
<div class="modal-header px-0 border-0">
<h5 class="text-bold">Bulk Volunteer Assignment</h5>
<button
class="border-0 bg-transparent h1"
data-bs-dismiss="modal"
type="button">
<i class="lni lni-cross-circle"></i>
</button>
</div>
<div class="modal-body px-0">
<div class="mb-30">
<div class="select-style-1">
<label for='supervisor_volunteer_supervisor_id'>
Choose a new supervisor from the dropdown below to reassign selected volunteers, or select “No Supervisor” to unassign volunteers. When you're ready, go ahead and click the "Confirm" button to apply the changes.
</label>
<select name='supervisor_volunteer[supervisor_id]' class='supervisor-bulk-assignment form-control' required="required">
<option value="default">Choose A Supervisor</option>
<option value="unassign">-- No Supervisor --</option>
<% @supervisors&.active&.each do |supervisor| %>
<option value="<%= supervisor.id %>"><%= supervisor.display_name %></option>
<% end %>
</select>
</div>
</div>
<div class="action d-flex flex-wrap justify-content-end">
<button
data-bs-dismiss="modal"
class="main-btn danger-btn-outline btn-hover m-1"
type="button"><i class="lni lni-ban mr-10"></i>
Close
</button>
<%= form.button type: :submit, class: "submit-bulk-assignment main-btn dark-btn btn-hover m-1" do %>
Confirm
<% end %>
</div>
</div>
</div>
</div>
</div>
</div>
<% end %>
</div>
</div>
</div>
</div>
</div>

</div>
</div>
3 changes: 3 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@
end
end
resources :supervisor_volunteers, only: %i[create] do
collection do
post :bulk_assignment
end
member do
patch :unassign
end
Expand Down
7 changes: 6 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,12 @@
t.index ["casa_org_id"], name: "index_judges_on_casa_org_id"
end

create_table "jwt_denylist", force: :cascade do |t|
t.string "jti", null: false
t.datetime "exp", null: false
t.index ["jti"], name: "index_jwt_denylist_on_jti"
end

create_table "languages", force: :cascade do |t|
t.string "name"
t.bigint "casa_org_id", null: false
Expand Down Expand Up @@ -392,7 +398,6 @@

create_table "learning_hours", force: :cascade do |t|
t.bigint "user_id", null: false
t.integer "learning_type", default: 5
t.string "name", null: false
t.integer "duration_minutes", null: false
t.integer "duration_hours", null: false
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,11 @@
"chart.js": "^4.4.0",
"chartjs-adapter-luxon": "^1.3.1",
"datatables.net-dt": "^1.13.6",
"datatables.net-select": "^1.7.0",
"esbuild": "^0.19.4",
"faker": "^5.5.3",
"jquery": "^3.7.1",
"jquery-datatables-checkboxes": "^1.2.14",
"js-cookie": "^3.0.5",
"jstz": "^2.1.1",
"lodash": "^4.17.21",
Expand Down
Loading

0 comments on commit 9f6b4b3

Please sign in to comment.