[ADD] RECRUITMENT: Group By filter to candidate view
This commit is contained in:
@@ -282,3 +282,14 @@ class SurveyFilter(FilterSet):
|
||||
exclude = [
|
||||
"sequence",
|
||||
]
|
||||
|
||||
class CandidateReGroup:
|
||||
"""
|
||||
Class to keep the field name for group by option
|
||||
"""
|
||||
fields = [
|
||||
("","select"),
|
||||
("recruitment_id","Recruitment"),
|
||||
("job_position_id","Job Position"),
|
||||
("hired", "Status"),
|
||||
]
|
||||
@@ -109,9 +109,6 @@
|
||||
<label class="oh-label">{% trans "End Date" %}</label>
|
||||
{{f.form.end_date}}
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -139,6 +136,34 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="oh-accordion">
|
||||
<div class="oh-accordion-header">{% trans "Group By" %}</div>
|
||||
<div class="oh-accordion-body">
|
||||
<div class="row">
|
||||
<div class="col-sm-12 col-md-12 col-lg-6">
|
||||
<div class="oh-input-group">
|
||||
<label class="oh-label">{% trans "Field" %}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12 col-md-12 col-lg-6">
|
||||
<div class="oh-input-group">
|
||||
<select
|
||||
class="oh-select mt-1"
|
||||
id="id_field"
|
||||
name="field"
|
||||
class="select2-selection select2-selection--single"
|
||||
id="gp"
|
||||
>
|
||||
{% for field in gp_fields %}
|
||||
<option value="{{ field.0 }}">{% trans field.1 %}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="oh-dropdown__filter-footer">
|
||||
|
||||
170
recruitment/templates/candidate/group_by.html
Normal file
170
recruitment/templates/candidate/group_by.html
Normal file
@@ -0,0 +1,170 @@
|
||||
{% load attendancefilters %} {% load basefilters %} {% load static %}
|
||||
{% load i18n %} {% include 'filter_tags.html' %}
|
||||
<div class="oh-card">
|
||||
{% dynamic_regroup data by field as candidate_grouper %}
|
||||
{% for candidate_list in candidate_grouper %}
|
||||
<div class="oh-accordion-meta">
|
||||
<div class="oh-accordion-meta__item">
|
||||
<div class="oh-accordion-meta__header">
|
||||
<span class="oh-accordion-meta__title pt-3 pb-3">
|
||||
<div class="oh-tabs__input-badge-container">
|
||||
<span
|
||||
class="oh-badge oh-badge--secondary oh-badge--small oh-badge--round mr-1"
|
||||
>
|
||||
{{candidate_list.list|length}}
|
||||
</span>
|
||||
{{candidate_list.grouper}}
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
<div class="oh-accordion-meta__body d-none">
|
||||
<div class="oh-sticky-table oh-sticky-table--no-overflow mb-5">
|
||||
<div class="oh-sticky-table">
|
||||
<div class="oh-sticky-table__table oh-table--sortable">
|
||||
<div class="oh-sticky-table__thead">
|
||||
<div class="oh-sticky-table__tr">
|
||||
<div class="oh-sticky-table__th" style="width:10px;">
|
||||
<input type="checkbox" class="oh-input oh-input__checkbox mt-1 mr-2 all-candidate" title="Select All"
|
||||
id = "allCandidate"/>
|
||||
</div>
|
||||
<div class="oh-sticky-table__th" hx-target='#section' hx-get="{% url 'search-candidate' %}?{{pd}}&orderby=name&view=list">{% trans "Candidates" %}</div>
|
||||
<div class="oh-sticky-table__th">{% trans "Email" %}</div>
|
||||
<div class="oh-sticky-table__th">{% trans "Phone" %}</div>
|
||||
<div class="oh-sticky-table__th">{% trans "Recruitment" %}</div>
|
||||
<div class="oh-sticky-table__th">{% trans "Job Position" %}</div>
|
||||
<div class="oh-sticky-table__th">{% trans "Resume" %}</div>
|
||||
{% comment %} <div class="oh-sticky-table__th"></div> {% endcomment %}
|
||||
<div class="oh-sticky-table__th"></div>
|
||||
</div>
|
||||
</div>
|
||||
{% for cand in candidate_list.list %}
|
||||
<div class="oh-sticky-table__tbody ui-sortable">
|
||||
<div class="oh-sticky-table__tr ui-sortable-handle">
|
||||
<div class="oh-sticky-table__sd {% if cand.canceled %} row-status--red
|
||||
{% elif cand.hired %} row-status--yellow
|
||||
{% else %} row-status--purple
|
||||
{% endif %}">
|
||||
<div class="">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="{{cand.id}}"
|
||||
class="oh-input candidate-checkbox oh-input__checkbox mt-2 mr-2 all-candidate-row"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="oh-sticky-table__td candidate {% if cand.hired %}hired-cand{% endif %}">
|
||||
<div class="d-flex">
|
||||
<div class="oh-profile oh-profile--md">
|
||||
<div class="oh-profile__avatar mr-1">
|
||||
<img src="{{cand.get_avatar}}"
|
||||
class="oh-profile__image"
|
||||
alt="Username" />
|
||||
</div>
|
||||
<span class="oh-profile__name oh-text--dark">{{cand}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a href="#" style="color: inherit;text-decoration: none;" class="oh-sticky-table__td ">{{cand.email}}</a>
|
||||
<a href="#" style="color: inherit;text-decoration: none;" class="oh-sticky-table__td">{{cand.mobile}}</a>
|
||||
<a href="#" style="color: inherit;text-decoration: none;"
|
||||
class="oh-sticky-table__td">{{cand.recruitment_id}}</a>
|
||||
<a href="#" style="color: inherit;text-decoration: none;"
|
||||
class="oh-sticky-table__td">{{cand.job_position_id}}</a>
|
||||
<a style="color: inherit;text-decoration: none;" class="oh-sticky-table__td" href="/media/{{cand.resume}}"
|
||||
target="_blank" rel="noopener noreferrer"><span class="oh-btn oh-btn--info"> {% trans "Resume" %}</span></a>
|
||||
{% comment %} <a href="#" style="color: inherit;text-decoration: none;" class="oh-sticky-table__td">
|
||||
{% if perms.recruitment.view_history %}
|
||||
<button hx-get="{% url 'candidate-history' cand.id %}" hx-target='#section'
|
||||
class="oh-btn oh-btn--info">history</button>
|
||||
{% endif %}
|
||||
</a> {% endcomment %}
|
||||
<div href="#" style="color: inherit;text-decoration: none;" class="oh-sticky-table__td">
|
||||
<div class="oh-btn-group">
|
||||
{% if perms.recruitment.change_candidate %}
|
||||
<a href="{% url 'rec-candidate-update' cand.id %}" hx-target='#updateFormContainer' hx-swap='innerHTML'
|
||||
class="oh-btn oh-btn--light-bkg w-50" title="Edit"><ion-icon name="create-outline"></ion-icon></a>
|
||||
{% endif %}
|
||||
{% if perms.recruitment.delete_candidate %}
|
||||
{% if cand.is_active %}
|
||||
<form action="{% url 'rec-candidate-archive' cand.id %}"title="Archive" onsubmit="return confirm('{% trans "Do you want to archive this candidate" %}')" method='post'
|
||||
class="w-50">
|
||||
{% csrf_token %}
|
||||
<button type='submit' class="oh-btn oh-btn--danger-outline oh-btn--light-bkg w-100"
|
||||
><ion-icon name="archive" title="Archive"></ion-icon></button>
|
||||
</form>
|
||||
{% else %}
|
||||
|
||||
<form action="{% url 'rec-candidate-archive' cand.id %}" title="Un Archive" onsubmit="return confirm('{% trans "Do you want to un-archive this candidate" %}')" method='post'
|
||||
class="w-50">
|
||||
{% csrf_token %}
|
||||
<button type='submit' class="oh-btn oh-btn--danger-outline oh-btn--light-bkg w-100"
|
||||
><ion-icon name="archive"></ion-icon></button>
|
||||
</form>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if perms.recruitment.delete_candidate %}
|
||||
<form action="{% url 'rec-candidate-delete' cand.id %}" onsubmit="return confirm('{% trans "Do you want to delete this candidate" %}')" method='post'
|
||||
onsubmit="Are you sure want to delete this candidate?" class="w-50">
|
||||
{% csrf_token %}
|
||||
<button type='submit' class="oh-btn oh-btn--danger-outline oh-btn--light-bkg w-100"
|
||||
title="Remove"><ion-icon name="trash-outline"></ion-icon></button>
|
||||
</form>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
<div class="oh-pagination">
|
||||
<span class="oh-pagination__page" data-toggle="modal" data-target="#addEmployeeModal">
|
||||
{% trans "Page" %} {{ data.number }} {% trans "of" %} {{ data.paginator.num_pages }}.
|
||||
</span>
|
||||
<nav class="oh-pagination__nav">
|
||||
<div class="oh-pagination__input-container me-3">
|
||||
<span class="oh-pagination__label me-1">{% trans "Page" %}</span>
|
||||
|
||||
<input type="number" name="page" class="oh-pagination__input" value="{{data.number}}"
|
||||
hx-get="{% url 'search-candidate' %}?{{pd}}&view=list" hx-target="#section" min="1" />
|
||||
<span class="oh-pagination__label">{% trans "of" %} {{data.paginator.num_pages}}</span>
|
||||
</div>
|
||||
|
||||
<ul class="oh-pagination__items">
|
||||
{% if data.has_previous %}
|
||||
<li class="oh-pagination__item oh-pagination__item--wide">
|
||||
<a hx-target='#section' hx-get="{% url 'search-candidate' %}?{{pd}}&page=1&view=list"
|
||||
class="oh-pagination__link" onclick=tickCandidateCheckboxes()>{% trans "First" %}</a>
|
||||
</li>
|
||||
<li class="oh-pagination__item oh-pagination__item--wide">
|
||||
<a hx-target='#section'
|
||||
hx-get="{% url 'search-candidate' %}?{{pd}}&page={{ data.previous_page_number }}&view=list"
|
||||
class="oh-pagination__link" onclick=tickCandidateCheckboxes()>{% trans "Previous" %}</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if data.has_next %}
|
||||
<li class="oh-pagination__item oh-pagination__item--wide">
|
||||
<a hx-target='#section' hx-get="{% url 'search-candidate' %}?{{pd}}&page={{ data.next_page_number }}&view=list"
|
||||
class="oh-pagination__link" onclick=tickCandidateCheckboxes()>{% trans "Next" %}</a>
|
||||
</li>
|
||||
<li class="oh-pagination__item oh-pagination__item--wide">
|
||||
<a hx-target='#section'
|
||||
hx-get="{% url 'search-candidate' %}?{{pd}}&page={{ data.paginator.num_pages }}&view=list"
|
||||
class="oh-pagination__link" onclick=tickCandidateCheckboxes()>{% trans "Last" %}</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
@@ -86,6 +86,13 @@ def candidate_search(request):
|
||||
if request.GET.get("view") == "list":
|
||||
template = "candidate/candidate_list.html"
|
||||
candidates = sortby(request, candidates, "orderby")
|
||||
|
||||
field = request.GET.get("field")
|
||||
if field != "" and field is not None:
|
||||
field_copy = field.replace(".", "__")
|
||||
candidates = candidates.order_by(field_copy)
|
||||
template = "candidate/group_by.html"
|
||||
|
||||
candidates = paginator_qry(candidates, request.GET.get("page"))
|
||||
return render(
|
||||
request,
|
||||
@@ -94,6 +101,7 @@ def candidate_search(request):
|
||||
"data": candidates,
|
||||
"pd": previous_data,
|
||||
"filter_dict": data_dict,
|
||||
"field":field,
|
||||
},
|
||||
)
|
||||
|
||||
@@ -116,19 +124,21 @@ def candidate_filter_view(request):
|
||||
"""
|
||||
This method is used for filter,pagination and search candidate.
|
||||
"""
|
||||
templete = "candidate/candidate_card.html"
|
||||
candidates = Candidate.objects.filter(is_active=True)
|
||||
template = "candidate/candidate_card.html"
|
||||
if request.GET.get('view') == 'list':
|
||||
templete = "candidate/candidate_list.html"
|
||||
template = "candidate/candidate_list.html"
|
||||
|
||||
previous_data = request.GET.urlencode()
|
||||
filter_obj = CandidateFilter(
|
||||
request.GET, queryset=Candidate.objects.filter(is_active=True)
|
||||
request.GET, queryset=candidates
|
||||
)
|
||||
paginator = Paginator(filter_obj.qs, 24)
|
||||
page_number = request.GET.get("page")
|
||||
page_obj = paginator.get_page(page_number)
|
||||
return render(
|
||||
request,
|
||||
templete,
|
||||
template,
|
||||
{"data": page_obj, "pd": previous_data},
|
||||
)
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ from horilla.decorators import permission_required, login_required, hx_request_r
|
||||
from base.methods import get_key_instances
|
||||
from recruitment.views.paginator_qry import paginator_qry
|
||||
from recruitment.models import Recruitment, Candidate, Stage, StageNote
|
||||
from recruitment.filters import CandidateFilter, RecruitmentFilter, StageFilter
|
||||
from recruitment.filters import CandidateFilter, CandidateReGroup, RecruitmentFilter, StageFilter
|
||||
from recruitment.methods import recruitment_manages
|
||||
from recruitment.decorators import manager_can_enter, recruitment_manager_can_enter
|
||||
from recruitment.forms import (
|
||||
@@ -843,6 +843,7 @@ def candidate_view(request):
|
||||
"export_obj": export_obj,
|
||||
"view_type": view_type,
|
||||
"filter_dict": data_dict,
|
||||
"gp_fields" : CandidateReGroup.fields
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user