[UPDT]filter tag

This commit is contained in:
Horilla
2023-09-04 09:55:24 +05:30
parent b624f091a7
commit e60d0480ee
9 changed files with 255 additions and 92 deletions

View File

@@ -1,6 +1,9 @@
import random
from employee.models import Employee
from django.apps import apps
from django.core.exceptions import ObjectDoesNotExist
from django.db.models import ForeignKey, ManyToManyField, OneToOneField
from django.utils.translation import gettext as _
from employee.models import Employee
def filtersubordinates(request, queryset, perm=None):
@@ -106,11 +109,12 @@ def sortby(request, queryset, key):
return queryset
def random_color_generator():
r = random.randint(0, 255)
g = random.randint(0, 255)
b = random.randint(0, 255)
if r==g or g==b or b==r:
if r == g or g == b or b == r:
random_color_generator()
return f"rgba({r}, {g}, {b} , 0.7)"
@@ -120,16 +124,16 @@ def random_color_generator():
def generate_colors(num_colors):
# Define a color palette with distinct colors
color_palette = [
"rgba(255, 99, 132, 1)", # Red
"rgba(54, 162, 235, 1)", # Blue
"rgba(255, 206, 86, 1)", # Yellow
"rgba(75, 192, 192, 1)", # Green
"rgba(255, 99, 132, 1)", # Red
"rgba(54, 162, 235, 1)", # Blue
"rgba(255, 206, 86, 1)", # Yellow
"rgba(75, 192, 192, 1)", # Green
"rgba(153, 102, 255, 1)", # Purple
"rgba(255, 159, 64, 1)", # Orange
"rgba(255, 159, 64, 1)", # Orange
]
if num_colors > len(color_palette):
for i in range(num_colors-len(color_palette)):
for i in range(num_colors - len(color_palette)):
color_palette.append(random_color_generator())
colors = []
@@ -137,4 +141,133 @@ def generate_colors(num_colors):
# color=random_color_generator()
colors.append(color_palette[i % len(color_palette)])
return colors
return colors
def get_key_instances(model, data_dict):
# Get all the models in the Django project
all_models = apps.get_models()
# Initialize a list to store related models include the function argument model as foreignkey
related_models = []
# Iterate through all models
for other_model in all_models:
# Iterate through fields of the model
for field in other_model._meta.fields:
# Check if the field is a ForeignKey and related to the function argument model
if isinstance(field, ForeignKey) and field.related_model == model:
related_models.append(other_model)
break
# Iterate through related models to filter instances
for related_model in related_models:
# Get all fields of the related model
related_model_fields = related_model._meta.get_fields()
# Iterate through fields to find ForeignKey fields
for field in related_model_fields:
if isinstance(field, ForeignKey):
# Get the related name and field name
related_name = field.related_query_name()
field_name = field.name
# Check if the related name exists in data_dict
if related_name in data_dict:
# Get the related_id from data_dict
related_id_list = data_dict[related_name]
related_id = int(related_id_list[0])
# Filter instances based on the field and related_id
filtered_instance = related_model.objects.filter(
**{field_name: related_id}
).first()
# Store the filtered instance back in data_dict
data_dict[related_name] = [str(filtered_instance)]
# Get all the fields in the argument model
model_fields = model._meta.get_fields()
foreign_key_field_names = [
field.name
for field in model_fields
if isinstance(field, ForeignKey or OneToOneField)
]
# Create a list of field names that are present in data_dict
present_foreign_key_field_names = [
key for key in foreign_key_field_names if key in data_dict
]
for field_name in present_foreign_key_field_names:
try:
# Get the integer value from data_dict for the field
field_value = int(data_dict[field_name][0])
# Get the related model of the ForeignKey field
related_model = model._meta.get_field(field_name).remote_field.model
# Get the instance of the related model using the field value
related_instance = related_model.objects.get(id=field_value)
# Update data_dict with the string representation of the instance
data_dict[field_name] = [str(related_instance)]
except (ObjectDoesNotExist, ValueError):
pass
# Create a list of field names that are ManyToManyField
many_to_many_field_names = [
field.name for field in model_fields if isinstance(field, ManyToManyField)
]
# Create a list of field names that are present in data_dict for ManyToManyFields
present_many_to_many_field_names = [
key for key in many_to_many_field_names if key in data_dict
]
for field_name in present_many_to_many_field_names:
try:
# Get the related model of the ManyToMany field
related_model = model._meta.get_field(field_name).remote_field.model
# Get a list of integer values from data_dict for the field
field_values = [int(value) for value in data_dict[field_name]]
# Filter instances of the related model based on the field values
related_instances = related_model.objects.filter(id__in=field_values)
# Update data_dict with the string representations of related instances
data_dict[field_name] = [str(instance) for instance in related_instances]
except (ObjectDoesNotExist, ValueError):
pass
nested_fields = [key for key in data_dict if "__" in key]
for key in nested_fields:
field_names = key.split("__")
field_values = data_dict[key]
if (
field_values != ["unknown"]
and field_values != ["true"]
and field_values != ["false"]
):
nested_instance = get_nested_instances(model, field_names, field_values)
if nested_instance is not None:
data_dict[key] = nested_instance
return data_dict
def get_nested_instances(model, field_names, field_values):
try:
related_model = model
for field_name in field_names:
try:
related_field = related_model._meta.get_field(field_name)
except:
pass
try:
related_model = related_field.remote_field.model
except:
pass
field_values = [int(value) for value in field_values]
related_instances = related_model.objects.filter(id__in=field_values)
return [str(instance) for instance in related_instances]
except (ObjectDoesNotExist, ValueError):
return None

View File

@@ -1,4 +1,5 @@
{% load i18n %}
{% load basefilters %}
{% if messages %}
<ul class="messages">
{% for message in messages %}
@@ -15,18 +16,20 @@
{% endif %}
<!-- filter items showing here -->
<div class="oh-filter-tag-container "
<div class="oh-filter-tag-container "
style="position: fixed;top: 150;z-index: 9999;">
{%for field,value in filter_dict.items %}
{%if value %}
<span class="oh-filter-tag filter-field" data-x-field="{{field}}" >{{field}}<button class="oh-filter-tag__close">
<ion-icon name="close-outline" role="img" class="md hydrated" aria-label="close outline"></ion-icon></button>
</span>
{%endif%}
{% endfor %}
</div>
<script>
{%for field,values in filter_dict.items %}
{%if values %}
<span class="oh-filter-tag filter-field" data-x-field="{{field}}" >
{{field|filter_field}} : {% for value in values%} {{ value|capfirst }}{% endfor %}
<button class="oh-filter-tag__close">
<ion-icon name="close-outline" role="img" class="md hydrated" aria-label="close outline"> </ion-icon>
</button>
</span>
{%endif%}
{% endfor %}
</div>
<script>
var form_submit_id = 'feedback-filter-form-submit'
$(document).ready(function () {
$('.filter-field').on('click',function(){
@@ -35,7 +38,7 @@
$('#'+form_submit_id).click()
})
});
</script>
</script>
<div class="oh-tabs__contents">
<div class="oh-tabs__content oh-tabs__content" id="tab_1">
<!-- Sticky Table for self feedback -->

View File

@@ -1,25 +1,19 @@
{% load i18n %}
{% load basefilters %}
<!-- filter items showing here -->
<div
class="oh-filter-tag-container"
style="position: fixed; top: 150; z-index: 9999"
>
{%for field,value in filter_dict.items %} {%if value %}
<span class="oh-filter-tag filter-field" data-x-field="{{field}}"
>{{field}}<button class="oh-filter-tag__close">
<ion-icon
name="close-outline"
role="img"
class="md hydrated"
aria-label="close outline"
></ion-icon>
</button>
</span>
{%endif%} {% endfor %}
<div class="oh-filter-tag-container "
style="position: fixed;top: 150;z-index: 9999;">
{%for field,values in filter_dict.items %}
{%if values %}
<span class="oh-filter-tag filter-field" data-x-field="{{field}}" >
{{field|filter_field}} : {% for value in values%} {{ value|capfirst }}{% endfor %}
<button class="oh-filter-tag__close">
<ion-icon name="close-outline" role="img" class="md hydrated" aria-label="close outline"> </ion-icon>
</button>
</span>
{%endif%}
{% endfor %}
</div>
<script>
var form_submit_id = "objective-filter-form-submit";
$(document).ready(function () {

View File

@@ -1,6 +1,17 @@
import json
import datetime
from django.http import HttpResponse
from urllib.parse import parse_qs
from django.http import HttpResponse, JsonResponse
from django.db.utils import IntegrityError
from django.db.models import Q
from django.forms import modelformset_factory
from django.contrib import messages
from django.core.paginator import Paginator
from django.utils.translation import gettext_lazy as _
from django.shortcuts import get_object_or_404, render, redirect
from horilla.decorators import manager_can_enter
from horilla.decorators import login_required, hx_request_required
from pms.filters import ObjectiveFilter, FeedbackFilter
from pms.models import (
EmployeeKeyResult,
EmployeeObjective,
@@ -14,13 +25,9 @@ from pms.models import (
KeyresultFeedback,
)
from base.models import Department, JobPosition
from base.methods import get_key_instances
from employee.models import Employee, EmployeeWorkInformation
from horilla.decorators import manager_can_enter
from django.http import JsonResponse
import json
from itertools import tee
from django.core.paginator import Paginator
from pms.filters import ObjectiveFilter, FeedbackFilter
from .forms import (
QuestionForm,
ObjectiveForm,
@@ -30,15 +37,7 @@ from .forms import (
PeriodForm,
QuestionTemplateForm,
)
from django.forms import modelformset_factory
from django.contrib import messages
from horilla.decorators import login_required, hx_request_required
from django.urls import reverse
from django.db.utils import IntegrityError
from django.db.models import Q
from django.utils.translation import gettext_lazy as _
from notifications.signals import notify
from urllib.parse import parse_qs
@login_required
@@ -194,7 +193,7 @@ def objective_delete(request, id):
return redirect(objective_list_view)
def objecitve_filter_pagination(request, objective_own, objective_all):
def objective_filter_pagination(request, objective_own, objective_all):
"""
This view takes two arguments, all_objective,own_objecitve and returns some objects.
Args:
@@ -205,7 +204,7 @@ def objecitve_filter_pagination(request, objective_own, objective_all):
"""
previous_data = request.environ["QUERY_STRING"]
initial_data = {"archive": False} # set initial value of archive filter to False
if request.GET.get("status") !="Closed":
if request.GET.get("status") != "Closed":
objective_own = objective_own.exclude(status="Closed")
objective_all = objective_all.exclude(status="Closed")
objective_filter_own = ObjectiveFilter(
@@ -221,8 +220,7 @@ def objecitve_filter_pagination(request, objective_own, objective_all):
objectives_all = objective_paginator_all.get_page(page_number)
now = datetime.datetime.now()
data_dict = parse_qs(previous_data)
# Print the dictionary
get_key_instances(EmployeeObjective, data_dict)
context = {
"superuser": "true",
"own_objectives": objectives_own,
@@ -256,7 +254,7 @@ def objective_list_view(request):
)
objective_own = objective_own.distinct()
objective_all = EmployeeObjective.objects.all().exclude(status="Closed")
context = objecitve_filter_pagination(request, objective_own, objective_all)
context = objective_filter_pagination(request, objective_own, objective_all)
elif is_manager:
# if user is a manager
@@ -275,7 +273,7 @@ def objective_list_view(request):
status="Closed"
)
objective_all = objective_all.distinct()
context = objecitve_filter_pagination(request, objective_own, objective_all)
context = objective_filter_pagination(request, objective_own, objective_all)
else:
# for normal user
objective_own = EmployeeObjective.objects.filter(employee_id=employee).exclude(
@@ -285,7 +283,7 @@ def objective_list_view(request):
)
objective_own = objective_own.distinct()
objective_all = EmployeeObjective.objects.none()
context = objecitve_filter_pagination(request, objective_own, objective_all)
context = objective_filter_pagination(request, objective_own, objective_all)
return render(request, "okr/objective_list_view.html", context)
@@ -315,7 +313,7 @@ def objective_list_search(request):
objective_all = EmployeeObjective.objects.filter(
employee_id__employee_first_name__icontains=objective_owner
)
context = objecitve_filter_pagination(request, objective_own, objective_all)
context = objective_filter_pagination(request, objective_own, objective_all)
elif is_manager:
# if user is a manager
@@ -326,7 +324,7 @@ def objective_list_search(request):
objective_all = EmployeeObjective.objects.filter(
employee_id__in=employees_ids
).filter(employee_id__employee_first_name__icontains=objective_owner)
context = objecitve_filter_pagination(request, objective_own, objective_all)
context = objective_filter_pagination(request, objective_own, objective_all)
else:
# for normal user
@@ -334,7 +332,7 @@ def objective_list_search(request):
employee_id__employee_first_name__icontains=objective_owner
)
objective_all = EmployeeObjective.objects.none()
context = objecitve_filter_pagination(request, objective_own, objective_all)
context = objective_filter_pagination(request, objective_own, objective_all)
return render(request, "okr/objective_list.html", context)
@@ -912,7 +910,7 @@ def filter_pagination_feedback(
feedbacks_all = feedback_paginator_all.get_page(page_number)
now = datetime.datetime.now()
data_dict = parse_qs(previous_data)
get_key_instances(Feedback, data_dict)
context = {
"superuser": "true",
"self_feedback": feedbacks_own,

View File

@@ -42,7 +42,7 @@
</div>
<div class="oh-dropdown__filter-footer">
<button
class="oh-btn oh-btn--secondary oh-btn--small w-100"
class="oh-btn oh-btn--secondary oh-btn--small w-100 filterButton"
id="filterSubmit"
>
{% trans "Filter" %}

View File

@@ -4,6 +4,7 @@
width: 280px;
}
</style>
{% include 'filter_tags.html' %}
<div class="oh-layout--grid-3">
{% for question in questions %}
<div class="oh-kanban-card">

View File

@@ -9,14 +9,14 @@ from urllib.parse import parse_qs
from django.shortcuts import render
from django.core.paginator import Paginator
from horilla.decorators import login_required, permission_required
from base.methods import sortby
from base.methods import sortby, get_key_instances
from recruitment.filters import (
CandidateFilter,
RecruitmentFilter,
StageFilter,
SurveyFilter,
)
from recruitment.models import Candidate
from recruitment.models import Candidate, Recruitment, Stage, RecruitmentSurvey
from recruitment.views.paginator_qry import paginator_qry
@@ -30,18 +30,22 @@ def recruitment_search(request):
previous_data = request.environ["QUERY_STRING"]
recruitment_obj = sortby(request, filter_obj.qs, "orderby")
data_dict = parse_qs(previous_data)
if request.GET.get("is_active") :
if data_dict["is_active"] == ['unknown']:
get_key_instances(Recruitment, data_dict)
if request.GET.get("is_active"):
if data_dict["is_active"] == ["unknown"]:
data_dict.pop("is_active")
return render(
request,
"recruitment/recruitment_component.html",
{
"data": paginator_qry(recruitment_obj, request.GET.get("page")),
"pd": previous_data,
"filter_dict":data_dict,
"filter_dict": data_dict,
},
)
@@ -56,10 +60,15 @@ def stage_search(request):
previous_data = request.environ["QUERY_STRING"]
stages = sortby(request, stages, "orderby")
data_dict = parse_qs(previous_data)
get_key_instances(Stage, data_dict)
return render(
request,
"stage/stage_component.html",
{"data": paginator_qry(stages, request.GET.get("page")), "pd": previous_data,"filter_dict":data_dict,},
{
"data": paginator_qry(stages, request.GET.get("page")),
"pd": previous_data,
"filter_dict": data_dict,
},
)
@@ -75,18 +84,28 @@ def candidate_search(request):
search = ""
candidates = Candidate.objects.filter(name__icontains=search)
candidates = CandidateFilter(request.GET, queryset=candidates).qs
data_dict = parse_qs(previous_data)
keys_to_remove = [key for key, value in data_dict.items() if value == ['unknown']]
for key in keys_to_remove:
data_dict.pop(key)
data_dict = []
if not request.GET.get("dashboard"):
data_dict = parse_qs(previous_data)
get_key_instances(Candidate, data_dict)
keys_to_remove = [key for key, value in data_dict.items() if value == ["unknown"]]
for key in keys_to_remove:
data_dict.pop(key)
template = "candidate/candidate_card.html"
if request.GET.get("view") == "list":
template = "candidate/candidate_list.html"
candidates = sortby(request, candidates, "orderby")
candidates = paginator_qry(candidates, request.GET.get("page"))
return render(request, template, {"data": candidates, "pd": previous_data,"filter_dict":data_dict,})
return render(
request,
template,
{
"data": candidates,
"pd": previous_data,
"filter_dict": data_dict,
},
)
@login_required
@@ -130,12 +149,14 @@ def filter_survey(request):
previous_data = request.environ["QUERY_STRING"]
filter_obj = SurveyFilter(request.GET)
questions = filter_obj.qs
data_dict = parse_qs(previous_data)
get_key_instances(RecruitmentSurvey, data_dict)
return render(
request,
"survey/survey-card.html",
{
"questions": paginator_qry(questions, request.GET.get("page")),
"pd": previous_data,
"filter_dict": data_dict,
},
)

View File

@@ -2,23 +2,25 @@
<!-- filter items showing here -->
<div class="oh-filter-tag-container "
style="position: fixed;top: 150px;z-index: 9999;">
{%for field,value in filter_dict.items %}
{%if value %}
<span class="oh-filter-tag filter-field" data-x-field="{{field}}" >{{field|filter_field}}<button class="oh-filter-tag__close">
<ion-icon name="close-outline" role="img" class="md hydrated" aria-label="close outline"></ion-icon></button>
</span>
{%endif%}
{% endfor %}
style="position: fixed;top: 150;z-index: 9999;">
{%for field,values in filter_dict.items %}
{%if values %}
<span class="oh-filter-tag filter-field" data-x-field="{{field}}" >
{{field|filter_field}} : {% for value in values%} {{ value|capfirst }}{% endfor %}
<button class="oh-filter-tag__close">
<ion-icon name="close-outline" role="img" class="md hydrated" aria-label="close outline"> </ion-icon>
</button>
</span>
{%endif%}
{% endfor %}
</div>
<script>
var form_submit_id = '.filterButton'
$(document).ready(function () {
$('.filter-field').on('click',function(){
const field_id = $(this).attr("data-x-field")
$('#id_'+field_id).val('')
// Update all elements with the same ID to have null values
$('[id="id_' + field_id + '"]').val('');
$(form_submit_id).click()
})
});

View File

@@ -1,4 +1,5 @@
{% load i18n %}
{% get_current_language as LANGUAGE_CODE %}
{% if messages %}
<div class="oh-alert-container">
{% for message in messages %}
@@ -18,7 +19,17 @@
{% if notification.unread %}
<span style="width: 10px;height: 10px;border-radius: 100%; background-color: hsl(8deg,77%,56%);display: inline-block;right: 5px;"></span>
{% endif %}
{% trans notification.verb %}
{% if LANGUAGE_CODE == 'ar' %}
<p class="oh-navbar__notification-text" :class="markRead ? '' : 'oh-navbar__notification-text--unread' ">{{ notification.data.verb_ar }}</p>
{% elif LANGUAGE_CODE == 'de' %}
<p class="oh-navbar__notification-text" :class="markRead ? '' : 'oh-navbar__notification-text--unread' ">{{ notification.data.verb_de }}</p>
{% elif LANGUAGE_CODE == 'fr' %}
<p class="oh-navbar__notification-text" :class="markRead ? '' : 'oh-navbar__notification-text--unread' ">{{ notification.data.verb_fr }}</p>
{% elif LANGUAGE_CODE == 'es' %}
<p class="oh-navbar__notification-text" :class="markRead ? '' : 'oh-navbar__notification-text--unread' ">{{ notification.data.verb_es }}</p>
{% else %}
<p class="oh-navbar__notification-text" :class="markRead ? '' : 'oh-navbar__notification-text--unread' ">{{ notification.verb }}</p>
{% endif %}
</span>
<ion-icon name="close-outline" hx-target="#allNotificationBody" hx-post="{% url 'delete-notifications' notification.id %}" role="img" aria-label="close outline"></ion-icon>
</div>