refactored approval system - now with comments
This commit is contained in:
parent
854b60bc8c
commit
c38e0c9bf8
@ -18,11 +18,6 @@ function updateVotes(data){
|
||||
$("[data-id=my-vote]").html(data.myVote);
|
||||
}
|
||||
|
||||
function updateVeto(data){
|
||||
$("[data-id=interview-request]").html(data.requestCopy);
|
||||
$("[data-id=interview-decline]").html(data.declineCopy);
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
$('[data-id=ajax-action]').each(function(){ handleAjaxResponse($(this)); });
|
||||
});
|
||||
@ -30,7 +25,3 @@ $(document).ready(function() {
|
||||
$(document).ready(function() {
|
||||
$('[data-id=vote-count]').each(function(){ handleAjaxResponse($(this), updateVotes); });
|
||||
});
|
||||
|
||||
$(document).ready(function() {
|
||||
$('[data-id=veto-status]').each(function(){ handleAjaxResponse($(this), updateVeto); });
|
||||
});
|
||||
|
@ -83,8 +83,32 @@
|
||||
& > div { flex: 1 1 auto; }
|
||||
}
|
||||
|
||||
.review_meta__votes,
|
||||
.review_meta__vetos {
|
||||
.review_meta__votes {
|
||||
margin-bottom: 15px;
|
||||
a { padding: 5px; }
|
||||
}
|
||||
|
||||
.review_meta__vetos {
|
||||
label {
|
||||
display: inline-block;
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
.review-status-comments {
|
||||
opacity: 0;
|
||||
padding: 15px 0;
|
||||
height: 0;
|
||||
max-height: 0;
|
||||
overflow: hidden;
|
||||
transition: all 0.500s;
|
||||
}
|
||||
|
||||
input:checked ~ .review-status-comments {
|
||||
opacity: 1;
|
||||
height: auto;
|
||||
max-height: 9999px;
|
||||
overflow: auto;
|
||||
transition: all 0.7500s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,22 +13,20 @@ module Admin
|
||||
current_user.cast_nay_on(@candidate)
|
||||
end
|
||||
|
||||
def approve
|
||||
def interview_request
|
||||
@candidate = Candidate.find_by(test_hash: params[:test_hash])
|
||||
authorize ReviewerVote.find_by(user_id: current_user.id, candidate_id: @candidate.id)
|
||||
|
||||
if current_user.approve_candidate(@candidate)
|
||||
RecruiterMailer.interview_requested(@candidate).deliver_later
|
||||
end
|
||||
current_user.review_candidate(@candidate, interview_params)
|
||||
RecruiterMailer.candidate_reviewed(@candidate).deliver_later
|
||||
redirect_to admin_result_path(@candidate.test_hash),
|
||||
flash: { notice: "Quiz #{interview_params[:review_status]}" }
|
||||
end
|
||||
|
||||
def decline
|
||||
@candidate = Candidate.find_by(test_hash: params[:test_hash])
|
||||
authorize ReviewerVote.find_by(user_id: current_user.id, candidate_id: @candidate.id)
|
||||
private
|
||||
|
||||
if current_user.decline_candidate(@candidate)
|
||||
RecruiterMailer.interview_declined(@candidate).deliver_later
|
||||
def interview_params
|
||||
params.permit(:review_status, :review_comments)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -15,7 +15,7 @@ class ReviewerVote < ApplicationRecord
|
||||
|
||||
enum veto: {
|
||||
approved: 1,
|
||||
rejected: 2
|
||||
declined: 2
|
||||
}
|
||||
|
||||
private
|
||||
|
@ -38,20 +38,16 @@ class User < ApplicationRecord
|
||||
vote.save
|
||||
end
|
||||
|
||||
def approve_candidate candidate
|
||||
def review_candidate candidate, parms_hash
|
||||
candidate = Candidate.find(candidate.to_i)
|
||||
|
||||
vote = votes.find_by(candidate_id: candidate.to_i)
|
||||
vote.veto = :approved
|
||||
candidate.update_attribute(:review_status, :approved) if vote.save
|
||||
end
|
||||
|
||||
def decline_candidate candidate
|
||||
candidate = Candidate.find(candidate.to_i)
|
||||
|
||||
vote = votes.find_by(candidate_id: candidate.to_i)
|
||||
vote.veto = :rejected
|
||||
candidate.update_attribute(:review_status, :declined) if vote.save
|
||||
vote.veto = parms_hash[:review_status]
|
||||
if vote.save
|
||||
# skipping validations on candidate because that's not the managers responsibility
|
||||
candidate.review_comments = parms_hash[:review_comments]
|
||||
candidate.update_attribute(:review_status, parms_hash[:review_status])
|
||||
end
|
||||
end
|
||||
|
||||
def my_vote candidate
|
||||
|
@ -23,22 +23,22 @@
|
||||
<% end %>
|
||||
|
||||
<% if current_user.acts_as_manager? %>
|
||||
<div class="review_meta__vetos" data-id="veto-status">
|
||||
<strong>Interview: </strong>
|
||||
<div class="review_meta__vetos">
|
||||
<%= form_tag admin_interview_path(test_hash: @candidate.test_hash) do %>
|
||||
<strong>Interview: </strong>
|
||||
|
||||
<% if !@candidate.approved? %>
|
||||
<%= link_to admin_approve_vote_path(test_hash: @candidate.test_hash), remote: true do %>
|
||||
<span data-id="interview-request">Yes</span>
|
||||
<% end %>
|
||||
<% else %>Yes<% end %>
|
||||
<%= radio_button_tag :review_status, :approved, checked = @candidate.approved? %>
|
||||
<%= label_tag :review_status_approved, "Yes" %>
|
||||
|
||||
<%= radio_button_tag :review_status, :declined, checked = @candidate.declined? %>
|
||||
<%= label_tag :review_status_declined, "No" %>
|
||||
|
||||
<% if !@candidate.declined? %>
|
||||
<%= link_to admin_decline_vote_path(test_hash: @candidate.test_hash), remote: true do %>
|
||||
<span data-id="interview-decline">No</span>
|
||||
<% end %>
|
||||
<% else %>No<% end %>
|
||||
|
||||
<div class="review-status-comments">
|
||||
<span>Review comments for recruiter</span>
|
||||
<%= text_area_tag :review_comments, @candidate.review_comments %>
|
||||
<%= submit_tag 'Send Request' %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% else %>
|
||||
|
||||
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
"message" : "Interview requested!",
|
||||
"requestCopy" : "Requested",
|
||||
"declineCopy" : "Decline Interview"
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
"message" : "Interview declined.",
|
||||
"requestCopy" : "Request Interview",
|
||||
"declineCopy" : "Declined"
|
||||
}
|
@ -55,10 +55,9 @@ Rails.application.routes.draw do
|
||||
post "/admin/comment/:test_hash/:id", to: "admin/comment#update", as: :admin_update_comment
|
||||
post "/admin/comment/:test_hash", to: "admin/comment#create", as: :admin_create_comment
|
||||
|
||||
get "admin/vote/:test_hash/up", to: "admin/vote#up", as: :admin_up_vote, defaults: { format: 'json' }
|
||||
get "admin/vote/:test_hash/down", to: "admin/vote#down", as: :admin_down_vote, defaults: { format: 'json' }
|
||||
get "admin/vote/:test_hash/approve", to: "admin/vote#approve", as: :admin_approve_vote, defaults: { format: 'json' }
|
||||
get "admin/vote/:test_hash/decline", to: "admin/vote#decline", as: :admin_decline_vote, defaults: { format: 'json' }
|
||||
get "admin/vote/:test_hash/up", to: "admin/vote#up", as: :admin_up_vote, defaults: { format: 'json' }
|
||||
get "admin/vote/:test_hash/down", to: "admin/vote#down", as: :admin_down_vote, defaults: { format: 'json' }
|
||||
post "admin/vote/:test_hash", to: "admin/vote#interview_request", as: :admin_interview
|
||||
|
||||
get "/admin", to: "admin/dashboard#show", as: :admin
|
||||
|
||||
|
@ -5,6 +5,24 @@ module Admin
|
||||
class VoteControllerTest < ActionDispatch::IntegrationTest
|
||||
include ActiveJob::TestHelper
|
||||
|
||||
test "reviewer can only vote after commenting" do
|
||||
auth_user users(:reviewer)
|
||||
henry = candidates(:henry)
|
||||
|
||||
assert_difference("Candidate.find(#{henry.id}).votes.yea.count", 0) do
|
||||
get admin_up_vote_url(henry.test_hash)
|
||||
end
|
||||
|
||||
post admin_create_comment_url(test_hash: henry.test_hash),
|
||||
params: { quiz_comment: { message: 'this is a comment to vote' } }
|
||||
|
||||
assert_difference("Candidate.find(#{henry.id}).votes.yea.count", 1) do
|
||||
get admin_up_vote_url(henry.test_hash)
|
||||
end
|
||||
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
test "reviewer can up vote henry" do
|
||||
auth_user users(:reviewer2)
|
||||
henry = candidates(:henry)
|
||||
@ -38,57 +56,19 @@ module Admin
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
test "manager can approve henry" do
|
||||
test "manager can approve henry and notify recruiter" do
|
||||
auth_user users(:manager)
|
||||
henry = candidates(:henry)
|
||||
get admin_approve_vote_url(henry.test_hash)
|
||||
|
||||
assert_equal 1, henry.votes.approved.count
|
||||
assert_equal 'approved', Candidate.find(henry.to_i).review_status, xhr: true
|
||||
assert_response :success
|
||||
data = JSON.parse(response.body)
|
||||
assert_match 'requested', data["message"]
|
||||
end
|
||||
|
||||
test "manager can decline henry" do
|
||||
auth_user users(:manager)
|
||||
henry = candidates(:henry)
|
||||
get admin_decline_vote_url(henry.test_hash), xhr: true
|
||||
|
||||
assert_equal 1, henry.votes.rejected.count
|
||||
assert_equal 'declined', Candidate.find(henry.to_i).review_status
|
||||
assert_response :success
|
||||
data = JSON.parse(response.body)
|
||||
assert_match 'declined', data["message"]
|
||||
end
|
||||
|
||||
test "should queue up a notification when manager approves henry" do
|
||||
auth_user users(:manager)
|
||||
henry = candidates(:henry)
|
||||
assert_enqueued_jobs 1 do
|
||||
get admin_approve_vote_url(henry.test_hash), xhr: true
|
||||
post admin_interview_url(henry.test_hash), params: {
|
||||
review_status: 'approved',
|
||||
review_comments: 'ipsum'
|
||||
}
|
||||
end
|
||||
assert_response :success
|
||||
data = JSON.parse(response.body)
|
||||
assert_match 'requested', data["message"]
|
||||
end
|
||||
|
||||
test "reviewer can only vote after commenting" do
|
||||
auth_user users(:reviewer)
|
||||
henry = candidates(:henry)
|
||||
|
||||
assert_difference("Candidate.find(#{henry.id}).votes.yea.count", 0) do
|
||||
get admin_up_vote_url(henry.test_hash)
|
||||
end
|
||||
|
||||
post admin_create_comment_url(test_hash: henry.test_hash),
|
||||
params: { quiz_comment: { message: 'this is a comment to vote' } }
|
||||
|
||||
assert_difference("Candidate.find(#{henry.id}).votes.yea.count", 1) do
|
||||
get admin_up_vote_url(henry.test_hash)
|
||||
end
|
||||
|
||||
assert_response :success
|
||||
assert_equal 'approved', Candidate.find(henry.to_i).review_status
|
||||
assert_equal 'ipsum', Candidate.find(henry.to_i).review_comments
|
||||
assert_redirected_to admin_result_url(henry.test_hash)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user