[ADD] PMS: Style updation in feedback detailed view
This commit is contained in:
@@ -56,14 +56,14 @@
|
||||
{% if resume %}
|
||||
<div class="col-12 col-md-6 col-lg-6 sticky">
|
||||
<iframe style="width: 100%;height:90vh" height="100" src="{{ resume.file.url }}" frameborder="0"></iframe>
|
||||
|
||||
|
||||
</div>
|
||||
{% else %}
|
||||
<p class="text-sm mb-2">{{recruitment.description|safe}}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{% comment %} <form action="" method="post" enctype="multipart/form-data"> {% endcomment %}
|
||||
{% if messages %}
|
||||
<div class="oh-alert-container">
|
||||
@@ -73,7 +73,7 @@
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<form class="col-span-12 lg:col-span-8 bg-white rounded-md shadow-card p-5 myform" method="post" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
<div class= "lg:h-[calc(100vh_-_160px)] overflow-hidden overflow-y-auto">
|
||||
@@ -116,17 +116,17 @@
|
||||
/>
|
||||
<label for="recuitment" >{% trans "Choose Job Position" %}</label>
|
||||
<div class="relative">
|
||||
<select name="job_position_id" class="oh-select oh-select2 w-100" style="height: 35px">
|
||||
<select name="job_position_id" class="oh-select oh-select2 w-100" style="height: 35px">
|
||||
{% for job in recruitment.open_positions.all %}
|
||||
<option value="{{job.id}}"> {{job.job_position}}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</select>
|
||||
<span class="absolute left-2 top-3 text-sm text-primary-600 pointer-events-none">
|
||||
<i class="fa-solid fa-briefcase"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div>
|
||||
<label for="portfolio">{% trans "Portfolio" %}</label>
|
||||
<div class="relative">
|
||||
@@ -141,7 +141,7 @@
|
||||
<div>
|
||||
<label class="required-star" for="gender">{% trans "Gender" %}</label>
|
||||
<div class="relative">
|
||||
{{form.gender}}
|
||||
{{form.gender}}
|
||||
<span class="absolute left-1 top-0 bottom-0 m-auto flex items-center ps-2 text-sm text-primary-600">
|
||||
<i class="fa-solid fa-circle-dot"></i></span>
|
||||
</div>
|
||||
@@ -267,7 +267,7 @@
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -295,7 +295,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function initSidebarToggle() {
|
||||
// Reusable Sidebar Toggle
|
||||
@@ -330,7 +330,7 @@
|
||||
{% if resume %}
|
||||
$("#resume").val(resume)
|
||||
{% endif %}
|
||||
|
||||
|
||||
$('form label').each(function() {
|
||||
var text = $(this).text();
|
||||
if (text.startsWith('*')) {
|
||||
@@ -365,22 +365,22 @@
|
||||
}
|
||||
return cookieValue;
|
||||
}
|
||||
|
||||
|
||||
function setIfEmpty(selector, value) {
|
||||
if ($(selector).val() === "" ){
|
||||
$(selector).val(value);
|
||||
$(selector).change();
|
||||
|
||||
|
||||
$("[name=country]").parent().find("span").remove()
|
||||
$("[name=country]").select2()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
$("#matching_resume").on("click", function(){
|
||||
var file = $(this).data("value");
|
||||
var resume_id = $(this).data("id");
|
||||
|
||||
|
||||
$.ajax({
|
||||
url: "{% url 'matching-resume-completion' %}",
|
||||
type: 'GET',
|
||||
@@ -397,7 +397,7 @@
|
||||
var dob = response.dob;
|
||||
var email = response.email_id;
|
||||
var zip = response.zip;
|
||||
|
||||
|
||||
setIfEmpty("[name='name']", full_name);
|
||||
setIfEmpty("[name='email']", email);
|
||||
setIfEmpty("[name='mobile']", phone);
|
||||
@@ -406,21 +406,21 @@
|
||||
setIfEmpty("[name='state']", state);
|
||||
setIfEmpty("[name='zip']", zip);
|
||||
$("[name='dob']").val(dob);
|
||||
|
||||
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error('File upload failed: ', status, error);
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
|
||||
$("#matching_resume").click()
|
||||
|
||||
|
||||
$("[name='resume']").on("change", function(){
|
||||
var formData = new FormData();
|
||||
var file = this.files[0];
|
||||
formData.append('resume', file);
|
||||
|
||||
|
||||
$.ajax({
|
||||
url: "{% url 'resume-completion' %}",
|
||||
type: 'POST',
|
||||
@@ -431,7 +431,7 @@
|
||||
'X-CSRFToken': getCookie("csrftoken")
|
||||
},
|
||||
success: function(response) {
|
||||
|
||||
|
||||
var full_name = response.full_name;
|
||||
var address = response.address;
|
||||
var country = response.country;
|
||||
@@ -440,7 +440,7 @@
|
||||
var dob = response.dob;
|
||||
var email = response.email_id;
|
||||
var zip = response.zip;
|
||||
|
||||
|
||||
setIfEmpty("[name='name']", full_name);
|
||||
setIfEmpty("[name='email']", email);
|
||||
setIfEmpty("[name='mobile']", phone);
|
||||
@@ -449,7 +449,7 @@
|
||||
setIfEmpty("[name='state']", state);
|
||||
setIfEmpty("[name='zip']", zip);
|
||||
$("[name='dob']").val(dob);
|
||||
|
||||
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error('File upload failed: ', status, error);
|
||||
@@ -458,7 +458,7 @@
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
<script>
|
||||
// Image preview
|
||||
document.getElementById("profileImageUpload").addEventListener("change", function () {
|
||||
|
||||
656
horilla_theme/templates/feedback/feedback_detailed_view.html
Normal file
656
horilla_theme/templates/feedback/feedback_detailed_view.html
Normal file
@@ -0,0 +1,656 @@
|
||||
{% extends 'index.html' %}
|
||||
{% block content %}
|
||||
{% include 'generic/components.html' %}
|
||||
{% load static i18n %}
|
||||
{% load i18n %}
|
||||
{% load basefilters %}
|
||||
{% load mathfilters %}
|
||||
|
||||
<style>
|
||||
.oh-profile__avatar-limit-height {
|
||||
height: 30px !important;
|
||||
}
|
||||
.oh-profile_name_custom {
|
||||
font-size: 13px;
|
||||
padding-left: 4px;
|
||||
}
|
||||
.oh-profile__image_custm {
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
}
|
||||
.avatars {
|
||||
display: flex;
|
||||
padding: 8px 10px 8px 10px;
|
||||
}
|
||||
|
||||
.avatars__item {
|
||||
background-color: #596376;
|
||||
border: 2px solid white;
|
||||
border-radius: 100%;
|
||||
color: #ffffff;
|
||||
display: block;
|
||||
font-family: sans-serif;
|
||||
font-size: 12px;
|
||||
font-weight: 100;
|
||||
height: 26px;
|
||||
width: 26px;
|
||||
line-height: 17px;
|
||||
text-align: center;
|
||||
transition: margin 0.1s ease-in-out;
|
||||
overflow: hidden;
|
||||
margin-left: -10px;
|
||||
}
|
||||
|
||||
.avatars__item:first-child {
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
.avatars__item:nth-child(2) {
|
||||
z-index: 4;
|
||||
}
|
||||
|
||||
.avatars__item:nth-child(3) {
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.avatars__item:nth-child(4) {
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.avatars__item:nth-child(5) {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.avatars__item:last-child {
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.avatars__item img {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.avatars:hover .avatars__item {
|
||||
margin-right: 10px;
|
||||
}
|
||||
</style>
|
||||
<div id="message"></div>
|
||||
<main :class="sidebarOpen ? 'oh-main__sidebar-visible' : ''">
|
||||
|
||||
<div class="bg-white p-3 rounded-md shadow-card mb-5">
|
||||
|
||||
<!-- Top Bar -->
|
||||
<div class="flex gap-2 md:gap-0 flex-wrap justify-between items-end mb-5 border-b border-dark-50 pb-3">
|
||||
<h3 class="text-md font-semibold">Feedback: {{ feedback }}</h3>
|
||||
|
||||
<div class="flex items-center flex-wrap gap-1">
|
||||
{% if perms.pms.change_feedback or request.user|is_reportingmanager %}
|
||||
<div class="relative dropdown-wrapper">
|
||||
<select id="status" name="feedback_status"
|
||||
class="px-5 py-2 h-full bg-white rounded-md text-xs border border-primary-500 hover:border-primary-600 transition duration-300"
|
||||
hx-post="{% url 'feedback-detailed-view-status' id=feedback.id %}"
|
||||
hx-trigger="change" hx-swap="afterend">
|
||||
<option value="{{feedback.status}}" selected>{% trans feedback.get_status_display %}</option>
|
||||
{% for value,label in feedback_status %}
|
||||
{% if feedback.status != label %}
|
||||
<option value="{{label}}">{% trans label %}</option>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
{% else %}
|
||||
<label class="px-5 py-2 bg-white rounded-md text-xs border border-primary-500">{{ feedback.get_status_display }}</label>
|
||||
{% endif %}
|
||||
|
||||
<!-- Action Buttons -->
|
||||
{% if perms.pms.change_feedback or perms.pms.delete_feedback or request.user.employee_get == feedback.created_by %}
|
||||
{% if not feedback_started and perms.pms.change_feedback or request.user.employee_get == feedback.created_by %}
|
||||
<button data-toggle="oh-modal-toggle"
|
||||
class="w-8 h-8 flex justify-center items-center bg-white border border-primary-500 hover:border-primary-600 rounded-md"
|
||||
data-target="#genericModal"
|
||||
hx-get="{% url 'feedback-update' feedback.id %}"
|
||||
hx-target="#genericModalBody"
|
||||
title="{% trans 'Edit' %}">
|
||||
<img src="/static/horilla_theme/assets/img/icons/edit.svg" width="16" alt="edit">
|
||||
</button>
|
||||
{% endif %}
|
||||
{% if perms.pms.delete_feedback %}
|
||||
<form action="{% url 'feedback-archive' id=feedback.id %}" method="post"
|
||||
onsubmit="return confirm('{% trans 'Do you want archive this Feedback ?' %}')">
|
||||
{% csrf_token %}
|
||||
<button class="w-8 h-8 flex justify-center items-center bg-white border border-primary-500 hover:border-primary-600 rounded-md"
|
||||
title="{% trans 'Archive' %}">
|
||||
<ion-icon name="archive" role="img" class="md hydrated"></ion-icon>
|
||||
</button>
|
||||
</form>
|
||||
{% if not feedback.feedback_answer.all %}
|
||||
<form action="{% url 'feedback-delete' id=feedback.id %}" method="post"
|
||||
onsubmit="return confirm('{% trans 'Do you want Delete this Feedback ?' %}')">
|
||||
{% csrf_token %}
|
||||
<button class="w-8 h-8 flex justify-center items-center bg-white border border-primary-500 hover:border-primary-600 rounded-md"
|
||||
title="{% trans 'Delete' %}">
|
||||
<img src="/static/horilla_theme/assets/img/icons/trash.svg" width="16" alt="delete">
|
||||
</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if request.user.employee_get == feedback.employee_id or perms.pms.change_feedback %}
|
||||
<a hx-get="{% url 'share-feedback' feedback.id %}"
|
||||
data-toggle="oh-modal-toggle"
|
||||
data-target="#objectCreateModal"
|
||||
hx-target="#objectCreateModalTarget"
|
||||
class="w-8 h-8 justify-center px-1 py-2 bg-primary-600 text-white rounded-md text-xs flex items-center gap-2 hover:bg-primary-800 transition duration-300"
|
||||
title="{% trans 'Request feedback' %}">
|
||||
<img src="/static/horilla_theme/assets/img/create.svg" width="18" alt="request" class="filter brightness-0 invert">
|
||||
</a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Feedback Info Section -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3">
|
||||
<div class="mb-2 flex gap-5 items-center">
|
||||
<span class="font-medium text-sm text-[#565E6C] w-28">{% trans "Owner" %}</span>
|
||||
<p class="text-sm font-semibold flex items-center gap-5">:
|
||||
<img src="{{ feedback.employee_id.get_avatar }}" alt="owner" class="w-6 h-6 rounded-full inline-block">
|
||||
<span>{{ feedback.employee_id }}</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="mb-2 flex gap-5 items-center">
|
||||
<span class="font-medium text-sm text-[#565E6C] w-28">{% trans "Start Date" %}</span>
|
||||
<p class="text-sm font-semibold flex items-center gap-5">: <span>{{ feedback.start_date }}</span></p>
|
||||
</div>
|
||||
|
||||
<div class="mb-2 flex gap-5 items-center">
|
||||
<span class="font-medium text-sm text-[#565E6C] w-28">{% trans "End Date" %}</span>
|
||||
<p class="text-sm font-semibold flex items-center gap-5">:
|
||||
<span> {{ feedback.end_date }}</span>
|
||||
<span title="Due {% if feedback.end_date == today %} today {% else %}in {{ feedback.end_date|sub:today }}{% endif %}">
|
||||
<ion-icon
|
||||
class="text-{% if feedback.end_date < today %}danger{% elif feedback.end_date == today %}warning{% else %}success{% endif %}"
|
||||
name="time-sharp"></ion-icon>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="mb-2 flex gap-5 items-center ">
|
||||
<span class="font-medium text-sm text-[#565E6C] w-48">{% trans "Answered Employees" %}</span>
|
||||
<p class="text-sm font-semibold flex items-center gap-5">:
|
||||
<ul class="flex items-center gap-1">
|
||||
{% for employee in employee_statics.yes %}
|
||||
{% if employee %}
|
||||
<li><a href="{% url 'employee-view-individual' employee.id %}"><img src="{{ employee.get_avatar }}" class="w-6 h-6 rounded-full" alt=""></a></li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul></p>
|
||||
</div>
|
||||
|
||||
<div class="mb-2 flex gap-5 items-center">
|
||||
<span class="font-medium text-sm text-[#565E6C] w-48">{% trans "Employees not answered yet" %}</span>
|
||||
<p class="text-sm font-semibold flex items-center gap-5">:
|
||||
<ul class="flex items-center gap-1">
|
||||
{% for employee in employee_statics.no %}
|
||||
{% if employee %}
|
||||
<li><a href="{% url 'employee-view-individual' employee.id %}"><img src="{{ employee.get_avatar }}" class="w-6 h-6 rounded-full" alt=""></a></li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul></p>
|
||||
</div>
|
||||
|
||||
{% if perms.pms.view_feedback and feedback.cyclic_feedback %}
|
||||
<div class="mb-2 flex gap-5 items-center">
|
||||
<span class="font-medium text-sm text-[#565E6C] w-48">{% trans "Cyclic feedback period" %}</span>
|
||||
<p class="text-sm font-semibold">: {{ feedback.cyclic_feedback_days_count }} {{ feedback.get_cyclic_feedback_period_display }}</p>
|
||||
</div>
|
||||
<div class="mb-2 flex gap-5 items-center">
|
||||
<span class="font-medium text-sm text-[#565E6C] w-48">{% trans "Next feedback on" %}</span>
|
||||
<p class="text-sm font-semibold">: {{ feedback.cyclic_next_start_date }} - {{ feedback.cyclic_next_end_date }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="bg-white p-3 rounded-md shadow-card ">
|
||||
|
||||
<div class="h-[calc(100vh_-_335px)] overflow-hidden overflow-y-auto">
|
||||
|
||||
<!-- Tab Buttons -->
|
||||
<div class="mytab flex sticky top-0 bg-white" role="tablist">
|
||||
<button
|
||||
class="tab-button px-4 py-2 text-sm font-medium text-blue-600 w-1/2 active"
|
||||
onclick="switchTab(event);"
|
||||
data-target="#feedback-answers"
|
||||
data-tab="feedback-answers">
|
||||
{% trans 'Feedback Answers' %}
|
||||
</button>
|
||||
<button
|
||||
class="tab-button px-4 py-2 text-sm font-medium w-1/2"
|
||||
onclick="switchTab(event); $('#feedback-overview-button').click()"
|
||||
data-target="#feedback-overview"
|
||||
data-tab='feedback-overview'>
|
||||
{% trans 'Feedback Overview' %}
|
||||
</button>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="tab-content mt-4">
|
||||
<div class="tab-pane" id="feedback-answers">
|
||||
<!-- Employee -->
|
||||
<div class="overflow-hidden overflow-x-auto">
|
||||
<table class="w-full">
|
||||
<thead class="bg-white">
|
||||
<tr class="border-b border-[#ececec]">
|
||||
<th class="text-sm font-medium text-left p-3" style="width:40%;">{% trans "Employee" %}</th>
|
||||
<th class="text-sm font-medium text-left p-3" style="width:28%;">{% trans "Status" %}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="border-b border-[#ebebeb]">
|
||||
<td class="text-sm text-left p-3 text-[#666]">
|
||||
<div class="flex gap-3 items-center font-normal text-sm">
|
||||
<img src="{{feedback.employee_id.get_avatar}}" class="rounded-full" alt="" width="30" />
|
||||
<span>{{feedback.employee_id}}</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-sm text-left p-3 text-[#666]">
|
||||
<span class="feedback-status" x-data-feedback-id="{{feedback.id}}" x-data-employee-id="{{feedback.employee_id.id}}"></span>
|
||||
</td>
|
||||
<td class="text-sm text-left p-3 text-[#666]">
|
||||
<button class="px-4 py-2 bg-primary-600 text-white rounded-md text-xs flex w-28 justify-center items-center gap-2 hover:bg-primary-800 transition duration-300 oh-activity-sidebar__open"
|
||||
data-target="#answerViewAccordion"
|
||||
hx-post="{%url 'feedback-detailed-view-answer' id=feedback.id emp_id=feedback.employee_id.id %}"
|
||||
hx-target="#answerView">
|
||||
{% trans "Answer View" %}
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- Manager -->
|
||||
{% if feedback.manager_id %}
|
||||
<div class="overflow-hidden overflow-x-auto mb-6">
|
||||
<table class="w-full">
|
||||
<thead class="bg-white">
|
||||
<tr class="border-b border-[#ececec]">
|
||||
<th class="text-sm font-medium text-left p-3" style="width:40%;">{% trans "Manager" %}</th>
|
||||
<th class="text-sm font-medium text-left p-3" style="width:28%;">{% trans "Status" %}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="border-b border-[#ebebeb]">
|
||||
<td class="text-sm text-left p-3 text-[#666]">
|
||||
<div class="flex gap-3 items-center font-normal text-sm">
|
||||
<img src="{{feedback.manager_id.get_avatar}}" class="rounded-full" alt="" width="30" />
|
||||
<span>{{feedback.manager_id}}</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-sm text-left p-3 text-[#666]">
|
||||
<span class="feedback-status" x-data-feedback-id="{{feedback.id}}" x-data-employee-id="{{feedback.manager_id.id}}"></span>
|
||||
</td>
|
||||
<td class="text-sm text-left p-3 text-[#666]">
|
||||
<button class="px-4 py-2 bg-primary-600 text-white rounded-md text-xs flex w-28 justify-center items-center gap-2 hover:bg-primary-800 transition duration-300 oh-activity-sidebar__open"
|
||||
data-target="#answerViewAccordion"
|
||||
hx-post="{%url 'feedback-detailed-view-answer' id=feedback.id emp_id=feedback.manager_id.id %}"
|
||||
hx-target="#answerView">
|
||||
{% trans "Answer View" %}
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- Subordinates -->
|
||||
{% if feedback.subordinate_id.all %}
|
||||
<div class="overflow-hidden overflow-x-auto mb-6">
|
||||
<table class="w-full">
|
||||
<thead class="bg-white">
|
||||
<tr class="border-b border-[#ececec]">
|
||||
<th class="text-sm font-medium text-left p-3" style="width:40%;">{% trans "Subordinates" %}</th>
|
||||
<th class="text-sm font-medium text-left p-3" style="width:28%;">{% trans "Status" %}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for employee in feedback.subordinate_id.all %}
|
||||
<tr class="border-b border-[#ebebeb]">
|
||||
<td class="text-sm text-left p-3 text-[#666]">
|
||||
<div class="flex gap-3 items-center font-normal text-sm">
|
||||
<img src="{{employee.get_avatar}}" class="rounded-full" alt="" width="30" />
|
||||
<span>{{employee}}</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-sm text-left p-3 text-[#666]">
|
||||
<span class="feedback-status" x-data-feedback-id="{{feedback.id}}" x-data-employee-id="{{employee.id}}"></span>
|
||||
</td>
|
||||
<td class="text-sm text-left p-3 text-[#666]">
|
||||
<button class="px-4 py-2 bg-primary-600 text-white rounded-md text-xs flex w-28 justify-center items-center gap-2 hover:bg-primary-800 transition duration-300 oh-activity-sidebar__open"
|
||||
data-target="#answerViewAccordion"
|
||||
hx-post="{%url 'feedback-detailed-view-answer' id=feedback.id emp_id=employee.id %}"
|
||||
hx-target="#answerView">
|
||||
{% trans "Answer View" %}
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- Colleague -->
|
||||
{% if feedback.colleague_id.all %}
|
||||
<div class="overflow-hidden overflow-x-auto mb-6">
|
||||
<table class="w-full">
|
||||
<thead class="bg-white">
|
||||
<tr class="border-b border-[#ececec]">
|
||||
<th class="text-sm font-medium text-left p-3" style="width:40%;">{% trans "Colleague" %}</th>
|
||||
<th class="text-sm font-medium text-left p-3" style="width:28%;">{% trans "Status" %}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for employee in feedback.colleague_id.all %}
|
||||
<tr class="border-b border-[#ebebeb]">
|
||||
<td class="text-sm text-left p-3 text-[#666]">
|
||||
<div class="flex gap-3 items-center font-normal text-sm">
|
||||
<img src="{{employee.get_avatar}}" class="rounded-full" alt="" width="30" />
|
||||
<span>{{employee}}</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-sm text-left p-3 text-[#666]">
|
||||
<span class="feedback-status" x-data-feedback-id="{{feedback.id}}" x-data-employee-id="{{employee.id}}"></span>
|
||||
</td>
|
||||
<td class="text-sm text-left p-3 text-[#666]">
|
||||
<button class="px-4 py-2 bg-primary-600 text-white rounded-md text-xs flex w-28 justify-center items-center gap-2 hover:bg-primary-800 transition duration-300 oh-activity-sidebar__open"
|
||||
data-target="#answerViewAccordion"
|
||||
hx-post="{%url 'feedback-detailed-view-answer' id=feedback.id emp_id=employee.id %}"
|
||||
hx-target="#answerView">
|
||||
{% trans "Answer View" %}
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- Others -->
|
||||
{% if feedback.others_id.all %}
|
||||
<div class="overflow-hidden overflow-x-auto mb-6">
|
||||
<table class="w-full">
|
||||
<thead class="bg-white">
|
||||
<tr class="border-b border-[#ececec]">
|
||||
<th class="text-sm font-medium text-left p-3" style="width:40%;">{% trans "Other Employees" %}</th>
|
||||
<th class="text-sm font-medium text-left p-3" style="width:28%;">{% trans "Status" %}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for employee in feedback.others_id.all %}
|
||||
<tr class="border-b border-[#ebebeb]">
|
||||
<td class="text-sm text-left p-3 text-[#666]">
|
||||
<div class="flex gap-3 items-center font-normal text-sm">
|
||||
<img src="{{employee.get_avatar}}" class="rounded-full" alt="" width="30" />
|
||||
<span>{{employee}}</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-sm text-left p-3 text-[#666]">
|
||||
<span class="feedback-status" x-data-feedback-id="{{feedback.id}}" x-data-employee-id="{{employee.id}}"></span>
|
||||
</td>
|
||||
<td class="text-sm text-left p-3 text-[#666]">
|
||||
<button class="px-4 py-2 bg-primary-600 text-white rounded-md text-xs flex w-28 justify-center items-center gap-2 hover:bg-primary-800 transition duration-300 oh-activity-sidebar__open"
|
||||
data-target="#answerViewAccordion"
|
||||
hx-post="{%url 'feedback-detailed-view-answer' id=feedback.id emp_id=employee.id %}"
|
||||
hx-target="#answerView">
|
||||
{% trans "Answer View" %}
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="tab-pane hidden" id="feedback-overview">
|
||||
<div id="feedback_overview_div"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<button
|
||||
hx-get="{% url 'get-feedback-overview' feedback.id %}"
|
||||
hx-target="#feedback-overview" id="feedback-overview-button" hidden>
|
||||
</button>
|
||||
</main>
|
||||
|
||||
|
||||
<!-- modals -->
|
||||
<div
|
||||
class="oh-modal"
|
||||
id="objectCreateModal"
|
||||
role="dialog"
|
||||
aria-labelledby="objectCreateModal"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<div class="oh-modal__dialog" id="objectCreateModalTarget"></div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<!-- answer off canvas -->
|
||||
<div class="oh-activity-sidebar" id="answerViewAccordion" style="z-index:1000">
|
||||
<div class="oh-activity-sidebar__header">
|
||||
<span id="closanswer" style="cursor: pointer;" title="{% trans 'Close' %}">
|
||||
<ion-icon
|
||||
name="chevron-back-outline"
|
||||
class="oh-activity-sidebar__header-icon me-2 oh-activity-sidebar__close"
|
||||
id="close"
|
||||
data-target="#activitySidebar"
|
||||
style="font-size: 24px;"
|
||||
></ion-icon>
|
||||
<span class="oh-activity-sidebar__title"> {% trans "Answers" %}</span>
|
||||
</div>
|
||||
<div class="oh-activity-sidebar__body">
|
||||
<ol class="oh-activity-sidebar__qa-list" role="list" id="answerView">
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<script src="{% static 'src/feedback/feedback_answer.js' %}"></script>
|
||||
<script src="{% static 'src/feedback/feedback_detailed_view.js' %}"></script>
|
||||
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
$("#close").attr(
|
||||
"class",
|
||||
"oh-activity-sidebar__header-icon me-2 oh-activity-sidebar__close md hydrated"
|
||||
);
|
||||
});
|
||||
$("#closanswer").click(function (e) {
|
||||
$("#answerViewAccordion").removeClass("oh-activity-sidebar--show");
|
||||
});
|
||||
|
||||
$(` .oh-activity-sidebar__open`).on("click", function () {
|
||||
let sideBarId = $(this).attr("data-target");
|
||||
$(`${sideBarId}`).addClass("oh-activity-sidebar--show");
|
||||
});
|
||||
|
||||
$(` .oh-activity-sidebar__open`).on("click", function () {
|
||||
$(".oh-modal--show").removeClass("oh-activity-sidebar__close");
|
||||
});
|
||||
|
||||
function get_collegues(element) {
|
||||
|
||||
if (typeof element === 'object')
|
||||
{
|
||||
var employee_id = $(element).val();
|
||||
}
|
||||
else {
|
||||
var employee_id = element
|
||||
}
|
||||
|
||||
|
||||
// Check if the employee_id is valid
|
||||
if (employee_id) {
|
||||
// Dynamically set the hx-vals attribute for the manager button
|
||||
$('#managerButton').attr('hx-vals', JSON.stringify({ employee_id: employee_id, data: 'manager' })).click();
|
||||
// Dynamically set the hx-vals attribute for the colleagues button
|
||||
$('#colleguesButton').attr('hx-vals', JSON.stringify({ employee_id: employee_id, data: 'colleagues' })).click();
|
||||
// Dynamically set the hx-vals attribute for the subordinates button
|
||||
$('#subordinatesButton').attr('hx-vals', JSON.stringify({ employee_id: employee_id, data: 'subordinates' })).click();
|
||||
// Dynamically set the hx-vals attribute for the keyresult button
|
||||
$('#keyresultButtton').attr('hx-vals', JSON.stringify({ employee_id: employee_id, data: 'keyresults' })).click();
|
||||
} else {
|
||||
console.error('Invalid employee_id');
|
||||
}
|
||||
}
|
||||
function changeCyclicFeedback(element) {
|
||||
if (element.checked) {
|
||||
$("#cyclic_feedback_period").show();
|
||||
$("#id_cyclic_feedback_days_count").attr("required", true);
|
||||
$("#id_cyclic_feedback_period").attr("required", true);
|
||||
} else {
|
||||
$("#cyclic_feedback_period").hide();
|
||||
$("#id_cyclic_feedback_days_count").attr("required", false);
|
||||
$("#id_cyclic_feedback_period").attr("required", false);
|
||||
}
|
||||
}
|
||||
function copyLink(link){
|
||||
var $temp = $("<input>");
|
||||
var $url = $(location).attr('href');
|
||||
$("body").append($temp);
|
||||
$temp.val(link).select();
|
||||
document.execCommand("copy");
|
||||
$temp.remove();
|
||||
Swal.fire({
|
||||
text: `Link copied ${link}`,
|
||||
icon: "success",
|
||||
showConfirmButton: false,
|
||||
timer: 3000, // Set the timer to 3000 milliseconds (3 seconds)
|
||||
timerProgressBar: true, // Show a progress bar as the timer counts down
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Script to load components and all notifications -->
|
||||
<script>
|
||||
async function loadComponent(elementId, path, callback) {
|
||||
try {
|
||||
const response = await fetch(path);
|
||||
const html = await response.text();
|
||||
document.getElementById(elementId).innerHTML = html;
|
||||
|
||||
if (typeof callback === "function") {
|
||||
callback(); // Run script after component loads
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error loading component:", error);
|
||||
}
|
||||
}
|
||||
|
||||
function initSidebarToggle() {
|
||||
// Reusable Sidebar Toggle
|
||||
document.querySelectorAll(".toggleSidemenu").forEach((button) => {
|
||||
button.addEventListener("click", () => {
|
||||
const sidebarId = button.getAttribute("data-sidebar");
|
||||
const sidebar = document.getElementById(sidebarId);
|
||||
if (sidebar) {
|
||||
sidebar.classList.toggle("active");
|
||||
document.body.classList.toggle("overflow-hidden");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
document.querySelectorAll(".closeSidemenu").forEach((button) => {
|
||||
button.addEventListener("click", () => {
|
||||
const sidebarId = button.getAttribute("data-sidebar");
|
||||
const sidebar = document.getElementById(sidebarId);
|
||||
if (sidebar) {
|
||||
sidebar.classList.remove("active");
|
||||
document.body.classList.remove("overflow-hidden");
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/flowbite@3.1.2/dist/flowbite.min.js"></script>
|
||||
|
||||
|
||||
|
||||
<!-- TAB DESIGN -->
|
||||
<script>
|
||||
const tabButtons = document.querySelectorAll(".tab-button");
|
||||
const tabPanes = document.querySelectorAll(".tab-pane");
|
||||
|
||||
tabButtons.forEach((btn) => {
|
||||
btn.addEventListener("click", () => {
|
||||
// Remove active class and hide all panes
|
||||
tabButtons.forEach((b) => b.classList.remove("active", "text-blue-600", "border-blue-500"));
|
||||
tabPanes.forEach((pane) => pane.classList.add("hidden"));
|
||||
|
||||
// Add active class to clicked button
|
||||
btn.classList.add("active", "text-blue-600", "border-blue-500");
|
||||
|
||||
// Show the selected tab
|
||||
const target = btn.getAttribute("data-tab");
|
||||
document.getElementById(target).classList.remove("hidden");
|
||||
});
|
||||
});
|
||||
|
||||
// Trigger default active
|
||||
tabButtons[0].click();
|
||||
</script>
|
||||
|
||||
<!-- ACCORDION -->
|
||||
<script>
|
||||
document.querySelectorAll('.accordion-btn').forEach((btn) => {
|
||||
btn.addEventListener('click', () => {
|
||||
const panel = btn.nextElementSibling;
|
||||
const icon = btn.querySelector('.icon');
|
||||
const isOpen = panel.style.maxHeight && panel.style.maxHeight !== "0px";
|
||||
|
||||
// Collapse all others (optional — comment this block if you want multiple open)
|
||||
document.querySelectorAll('.accordion-panel').forEach(p => {
|
||||
p.style.maxHeight = null;
|
||||
p.previousElementSibling.querySelector('.icon').textContent = '+';
|
||||
p.previousElementSibling.classList.remove("bg-[#e54f38]", "text-white");
|
||||
p.previousElementSibling.classList.add("bg-[#fff5f1]", "text-[#e54f38]");
|
||||
});
|
||||
|
||||
// Toggle current
|
||||
if (!isOpen) {
|
||||
panel.style.maxHeight = panel.scrollHeight + 'px';
|
||||
icon.textContent = '−';
|
||||
btn.classList.remove("bg-[#fff5f1]", "text-[#e54f38]");
|
||||
btn.classList.add("bg-[#fff5f1]", "text-[#e54f38]");
|
||||
} else {
|
||||
panel.style.maxHeight = null;
|
||||
icon.textContent = '+';
|
||||
btn.classList.remove("bg-[#e54f38]", "text-white");
|
||||
btn.classList.add("bg-[#fff5f1]", "text-[#e54f38]");
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,132 @@
|
||||
{% load i18n %}
|
||||
{% for answer in answers %}
|
||||
<li class="oh-activity-sidebar__qa-item">
|
||||
<span class="oh-activity-sidebar__q"> {{forloop.counter}}. {{answer.question_id.question}}?</span>
|
||||
|
||||
{% if answer.question_id.question_type == '1' %}
|
||||
<span class="oh-activity-sidebar__a">{{ answer.answer.answer}}.</span>
|
||||
{% endif %}
|
||||
|
||||
{% if answer.question_id.question_type == '2' %}
|
||||
<ul class="flex gap-2 text-lg ps-4 mb-4">
|
||||
{% for i in "12345" %}
|
||||
<li>
|
||||
<i class="fa-solid fa-star {% if i <= answer.answer.answer %}text-[#FFA800]{% else %}text-[#dfdfdf]{% endif %}"></i>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
{% if answer.question_id.question_type == '3' %}
|
||||
<div class="oh-input__group">
|
||||
<div class="oh-input-picker-group">
|
||||
<div class="oh-input-picker oh-input-picker--selected boolean-colour ">
|
||||
{{answer.answer.answer}}
|
||||
<input type="radio" selected />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if answer.question_id.question_type == '4' %}
|
||||
<div class="d-block">
|
||||
<ul class="oh-questions mt-2">
|
||||
<li class="oh-questions__answer">
|
||||
<div class="oh-radio">
|
||||
<input type="radio" class="oh-radio " id="answer1" name="answer{{q.id}}" value="{{option.option_a}}"
|
||||
checked />
|
||||
<span class="oh-radio__checkmark"></span>
|
||||
<label class="oh-label" for="answer1"> {{answer.answer.answer}}</label>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if answer.question_id.question_type == '5' %}
|
||||
<div class="d-block">
|
||||
<div class="oh-input-picker-group oh-input-picker-group--resp mt-2">
|
||||
<div class="oh-input-picker oh-input-picker--likert likert-colour oh-input-picker--selected ">
|
||||
{{answer.answer.answer}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</li>
|
||||
|
||||
{% endfor %}
|
||||
{% if kr_feedbacks %}
|
||||
<hr/>
|
||||
<span class="oh-activity-sidebar__q" style="font-size: medium;">{% trans "Key results" %}</span>
|
||||
{% for kr_feedback in kr_feedbacks %}
|
||||
<li class="oh-activity-sidebar__qa-item">
|
||||
<span class="oh-activity-sidebar__q"> {{forloop.counter}}. {{kr_feedback.key_result_id.key_result_id}}</span>
|
||||
<div class="d-block">
|
||||
<div class="oh-input-picker-group oh-input-picker-group--resp mt-2">
|
||||
<div class="oh-input-picker oh-input-picker--likert oh-input-picker--selected
|
||||
{% if kr_feedback.answer.answer == "Bad" %}
|
||||
oh-input-picker--1
|
||||
{% elif kr_feedback.answer.answer == "Average" %}
|
||||
oh-input-picker--2
|
||||
{% elif kr_feedback.answer.answer == "Good" %}
|
||||
oh-input-picker--3
|
||||
{% elif kr_feedback.answer.answer == "Perfect" %}
|
||||
oh-input-picker--4
|
||||
{% endif %}
|
||||
"
|
||||
>
|
||||
{{ kr_feedback.answer.answer }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
<script>
|
||||
|
||||
$(document).ready(function () {
|
||||
// answer color for likert
|
||||
var booleanText = $('.boolean-colour').text().trim()
|
||||
var booleanEl = $('.boolean-colour')
|
||||
var red = "oh-input-picker--1"
|
||||
var orange = "oh-input-picker--2"
|
||||
var yellow = "oh-input-picker--3"
|
||||
var light_green = "oh-input-picker--4"
|
||||
var green = "oh-input-picker--5"
|
||||
|
||||
$('.likert-colour').each(function() {
|
||||
var likertText = $(this).text().trim()
|
||||
|
||||
if (likertText === 'Strongly Agree'){
|
||||
$(this).addClass(green)
|
||||
}
|
||||
else if (likertText === 'Agree'){
|
||||
$(this).addClass(light_green)
|
||||
}
|
||||
else if (likertText === 'Neutral'){
|
||||
$(this).addClass(yellow)
|
||||
}
|
||||
else if (likertText === 'Disagree'){
|
||||
$(this).addClass(orange)
|
||||
}
|
||||
else if (likertText === 'Strongly Disagree'){
|
||||
$(this).addClass(red)
|
||||
}
|
||||
});
|
||||
|
||||
// boolean text colour adding
|
||||
$('.boolean-colour').each(function() {
|
||||
var booleanText = $(this).text().trim()
|
||||
|
||||
if (booleanText === 'yes'){
|
||||
$(this).addClass(green)
|
||||
}
|
||||
else if (booleanText === 'no'){
|
||||
$(this).addClass(red)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
});
|
||||
</script>
|
||||
133
horilla_theme/templates/feedback/feedback_overview.html
Normal file
133
horilla_theme/templates/feedback/feedback_overview.html
Normal file
@@ -0,0 +1,133 @@
|
||||
|
||||
{% load i18n %}
|
||||
<div class="accordion-wrapper space-y-2">
|
||||
{% for question, answers in feedback_overview.items %}
|
||||
<div class="accordion-item border border-primary-300 rounded-md overflow-hidden">
|
||||
|
||||
<!-- Accordion Button -->
|
||||
<button
|
||||
class="accordion-btn w-full flex justify-between items-center px-4 py-2 bg-[#fff5f1] text-[#e54f38] text-sm transition-all">
|
||||
<div class="flex items-center gap-2">
|
||||
{{ question }}
|
||||
</div>
|
||||
<div class="flex items-center gap-5">
|
||||
<span class="icon text-xl font-bold">+</span>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<!-- Accordion Panel -->
|
||||
<div class="accordion-panel max-h-0 overflow-hidden transition-all duration-300 bg-white px-4 text-sm text-gray-700">
|
||||
<div class="py-3">
|
||||
{% if answers %}
|
||||
<table class="w-full">
|
||||
<thead class="bg-white">
|
||||
<tr class="border-b border-[#ececec]">
|
||||
<th class="text-sm font-medium text-left p-3">{% trans "Employee" %}</th>
|
||||
<th class="text-sm font-medium text-left p-3">{% trans "Answer" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for answer in answers %}
|
||||
{% for employee, value in answer.items %}
|
||||
<tr class="border-b border-[#ebebeb]">
|
||||
<td class="text-sm text-left p-3 text-[#666]">
|
||||
<div class="flex gap-3 items-center font-normal text-sm">
|
||||
<img src="{{ employee.get_avatar }}" class="rounded-full" alt="" width="30" />
|
||||
<span>{{ employee }}</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-sm text-left p-3 text-[#666]">
|
||||
{% if value.1.type == '1' %}
|
||||
<span class="oh-activity-sidebar__a">{{ value.0.answer }}</span>
|
||||
{% elif value.1.type == '2' %}
|
||||
<ul class="flex gap-2 text-lg ps-4 mb-4">
|
||||
{% for i in "12345" %}
|
||||
<li>
|
||||
<i class="fa-solid fa-star {% if i <= value.0.answer %}text-[#FFA800]{% else %}text-[#dfdfdf]{% endif %}"></i>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
{% elif value.1.type == '3' %}
|
||||
<div class="oh-input__group">
|
||||
<div class="oh-input-picker-group">
|
||||
<div class="oh-input-picker oh-input-picker--selected boolean-colour">
|
||||
{{ value.0.answer }}
|
||||
<input type="radio" selected />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% elif value.1.type == '4' %}
|
||||
<div class="d-block">
|
||||
<label class="oh-label" for="answer1">{{ value.0.answer }}</label>
|
||||
</div>
|
||||
{% elif value.1.type == '5' %}
|
||||
<div class="d-block mt-2">
|
||||
<div class="oh-input-picker-group oh-input-picker-group--resp">
|
||||
<div class="oh-input-picker oh-input-picker--likert likert-colour oh-input-picker--selected">
|
||||
{{ value.0.answer }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% elif value.1.type == '6' %}
|
||||
<div class="mt-2">
|
||||
<div class="oh-input-picker-group oh-input-picker-group--resp">
|
||||
<div class="oh-input-picker oh-input-picker--likert oh-input-picker--selected
|
||||
{% if value.0.answer == 'Bad' %} oh-input-picker--1
|
||||
{% elif value.0.answer == 'Average' %} oh-input-picker--2
|
||||
{% elif value.0.answer == 'Good' %} oh-input-picker--3
|
||||
{% elif value.0.answer == 'Perfect' %} oh-input-picker--4
|
||||
{% endif %}
|
||||
">
|
||||
{{ value.0.answer }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% else %}
|
||||
<p class="py-2 text-gray-500 text-sm">{% trans "No answers yet." %}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
|
||||
<!-- ACCORDION -->
|
||||
<script>
|
||||
document.querySelectorAll('.accordion-btn').forEach((btn) => {
|
||||
btn.addEventListener('click', () => {
|
||||
const panel = btn.nextElementSibling;
|
||||
const icon = btn.querySelector('.icon');
|
||||
const isOpen = panel.style.maxHeight && panel.style.maxHeight !== "0px";
|
||||
|
||||
// Collapse all others (optional — comment this block if you want multiple open)
|
||||
document.querySelectorAll('.accordion-panel').forEach(p => {
|
||||
p.style.maxHeight = null;
|
||||
p.previousElementSibling.querySelector('.icon').textContent = '+';
|
||||
p.previousElementSibling.classList.remove("bg-[#e54f38]", "text-white");
|
||||
p.previousElementSibling.classList.add("bg-[#fff5f1]", "text-[#e54f38]");
|
||||
});
|
||||
|
||||
// Toggle current
|
||||
if (!isOpen) {
|
||||
panel.style.maxHeight = panel.scrollHeight + 'px';
|
||||
icon.textContent = '−';
|
||||
btn.classList.remove("bg-[#fff5f1]", "text-[#e54f38]");
|
||||
btn.classList.add("bg-[#fff5f1]", "text-[#e54f38]");
|
||||
} else {
|
||||
panel.style.maxHeight = null;
|
||||
icon.textContent = '+';
|
||||
btn.classList.remove("bg-[#e54f38]", "text-white");
|
||||
btn.classList.add("bg-[#fff5f1]", "text-[#e54f38]");
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
84
horilla_theme/templates/generic/filter_result.html
Normal file
84
horilla_theme/templates/generic/filter_result.html
Normal file
@@ -0,0 +1,84 @@
|
||||
{% load static i18n generic_template_filters %}
|
||||
<style>
|
||||
.userbox {
|
||||
border: 1px solid #eaeaea;
|
||||
}
|
||||
|
||||
.userbox.active {
|
||||
background-color: rgb(255 245 241 / var(--tw-bg-opacity, 1)) !important;
|
||||
}
|
||||
|
||||
.userbox.active button:not(.text-xs button) {
|
||||
background-color: rgb(249 83 58) !important;
|
||||
}
|
||||
</style>
|
||||
<div class="userbox p-4 rounded-md mb-2 active">
|
||||
<div class="flex flex-col gap-3 relative">
|
||||
{% if actions %}
|
||||
<div class="absolute inline-block dropdown-wrapper right-0 -top-1">
|
||||
<a class="cursor-pointer dropdown-toggle"><i class="fa-solid fa-ellipsis-vertical text-black"></i></a>
|
||||
<!-- Dropdown Content -->
|
||||
<div class="dropdown-menu absolute right-0 min-w-[100px] bg-white rounded-lg shadow-card py-2 hidden z-50 transition-all duration-200">
|
||||
<ul class="text-xs" style="width: ;">
|
||||
{% for action in actions %}
|
||||
{% if action.accessibility|accessibility:instance %}
|
||||
<li>
|
||||
<a href="#" class="w-full text-left px-3 py-1 hover:text-primary-600 transition duration-300 oh-profile-dropdown-link" {{ action.attrs|format:instance|safe }}>
|
||||
{% comment %} <img src="{{ action.src }}" style="width: 20px; height: auto" title="{{ action.title }}" /> {% endcomment %}
|
||||
<button style="border: none; background: transparent">{{ action.title }}</button>
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="flex items-center gap-3">
|
||||
<img style="border-radius :30px ;overflow :hidden;" src="{{ object.get_avatar }}" alt="" width="35" />
|
||||
<h5 class="mb-1 font-medium text-sm">{{ instance.get_full_name }}</h5>
|
||||
</div>
|
||||
<div class="flex items-center justify-between gap-2">
|
||||
<div>
|
||||
<p class="text-[13px] text-[#565E6C] mb-1">{{ instance.get_subtitle }}</p>
|
||||
</div>
|
||||
<div>
|
||||
<button hx-get="{{ instance.get_profile_url }}" hx-target="#{{ view_id|safe }}" hx-swap="outerHTML" class="active w-8 h-8 rounded-md bg-[#f7f7f7] bg-primary-600 flex items-center justify-center text-white text-xs transition duration-300 hover:bg-primary-700"><i class="fa-solid fa-angle-right"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% for object in instances|slice:'0:9' %}
|
||||
{% if not object.pk == instance.pk %}
|
||||
<div class="userbox p-4 rounded-md mb-2">
|
||||
<div class="flex flex-col gap-3 relative">
|
||||
<div class="absolute inline-block dropdown-wrapper right-0 -top-1">
|
||||
<a class="cursor-pointer dropdown-toggle"><i class="fa-solid fa-ellipsis-vertical text-black"></i></a>
|
||||
<!-- Dropdown Content -->
|
||||
<div class="dropdown-menu absolute right-0 min-w-[100px] bg-white rounded-lg shadow-card py-2 hidden z-50 transition-all duration-200">
|
||||
<ul class="text-xs">
|
||||
<li>
|
||||
<button class="w-full text-left px-3 py-1 hover:text-primary-600 transition duration-300">Edit</button>
|
||||
</li>
|
||||
<li>
|
||||
<button class="w-full text-left px-3 py-1 hover:text-primary-600 transition duration-300">Delete</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-3">
|
||||
<img style="border-radius :30px ;overflow :hidden;" src="{{ object.get_avatar }}" alt="" width="35" />
|
||||
<h5 class="mb-1 font-medium text-sm">{{ object.get_full_name }}</h5>
|
||||
</div>
|
||||
<div class="flex items-center justify-between gap-2">
|
||||
<div>
|
||||
<p class="text-[13px] text-[#565E6C] mb-1">{{ object.get_subtitle }}</p>
|
||||
</div>
|
||||
<div>
|
||||
<button hx-get="{{ object.get_profile_url }}" hx-target="#{{ view_id|safe }}" hx-swap="outerHTML" class="active w-8 h-8 rounded-md bg-[#f7f7f7] bg-primary-600 flex items-center justify-center text-white text-xs transition duration-300 hover:bg-primary-700"><i class="fa-solid fa-angle-right"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
@@ -89,7 +89,7 @@
|
||||
|
||||
|
||||
{% if request.user.employee_get in emp_objective.objective_id.managers.all or emp_objective.employee_id == request.user.employee_get or perms.pms.view_employeekeyresult %}
|
||||
<a class="cursor-pointer px-2 py-1 text-sm bg-primary-300 text-primary-600 rounded-sm w-7 h-7 flex items-center justify-center hover:bg-primary-600 hover:text-white transition"
|
||||
<a class="oh-activity-sidebar__open cursor-pointer px-2 py-1 text-sm bg-primary-300 text-primary-600 rounded-sm w-7 h-7 flex items-center justify-center hover:bg-primary-600 hover:text-white transition"
|
||||
hx-get='{% url "objective-detailed-view-activity" emp_objective.id %}'
|
||||
hx-target="#sidebarModalBody4"
|
||||
data-target="#sidebarModal4"
|
||||
@@ -176,29 +176,13 @@
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Modals -->
|
||||
<!-- Activity Sidebar -->
|
||||
|
||||
<div class="sidebarModal overflow-hidden overflow-y-auto" id="sidebarModal4">
|
||||
<!-- <button class="closebtn closeSidemenu absolute top-3 right-3" data-sidebar="sidebarModal3"><i
|
||||
class="fa-solid fa-xmark"></i></button> -->
|
||||
|
||||
<div class="flex justify-between items-center mb-4">
|
||||
<h3 class="font-semibold flex items-center gap-2">
|
||||
<button
|
||||
class="closebtn closeSidemenu cursor-pointer text-xs group text-primary-600 w-6 h-6 bg-primary-100 hover:bg-primary-600 hover:text-white rounded-full transition duration-300 flex items-center justify-center"
|
||||
data-sidebar="sidebarModal4"
|
||||
>
|
||||
<i class="fa-solid fa-angle-right"></i></button
|
||||
>{% trans "All Notifications" %}
|
||||
</h3>
|
||||
<button
|
||||
class="text-primary-600 text-xs flex justify-center font-semibold hover:text-[#ac3b2a] transition duration-300"
|
||||
>
|
||||
{% trans "Clear All" %}
|
||||
</button>
|
||||
<div class="oh-activity-sidebar" id="sidebarModal4" style="z-index:1000">
|
||||
<div class="oh-activity-sidebar__body">
|
||||
<ol class="oh-activity-sidebar__qa-list" role="list" id="sidebarModalBody4">
|
||||
</ol>
|
||||
</div>
|
||||
<div class="" id="sidebarModalBody4"></div>
|
||||
<!--sidecont-->
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
</head>
|
||||
|
||||
<body class="bg-secondary-50 font-[Inter,_sans-serif]">
|
||||
|
||||
|
||||
{% if messages %}
|
||||
<div class="oh-alert-container">
|
||||
{% for message in messages %}
|
||||
@@ -52,7 +52,7 @@
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
<div class="p-5 flex justify-center items-center h-screen flex-col">
|
||||
<div class="w-full max-w-5xl pl-5 flex justify-start mb-2">
|
||||
{% if request.user.is_authenticated %}
|
||||
@@ -187,11 +187,11 @@
|
||||
document.body.classList.toggle("overflow-hidden");
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
|
||||
@@ -259,7 +259,7 @@ urlpatterns = [
|
||||
cbvs.BulkFeedbackFormView.as_view(),
|
||||
name="bulk-feedback-create",
|
||||
),
|
||||
path("feedback-update/<int:id>", views.feedback_update, name="feedback-update"),
|
||||
# path("feedback-update/<int:id>", views.feedback_update, name="feedback-update"),
|
||||
path("feedback-delete/<int:id>", views.feedback_delete, name="feedback-delete"),
|
||||
path("feedback-archive/<int:id>", views.feedback_archive, name="feedback-archive"),
|
||||
path("get-collegues", views.get_collegues, name="get-collegues"),
|
||||
|
||||
Reference in New Issue
Block a user