[ADD] PMS: Feedback overview

This commit is contained in:
Horilla
2024-09-19 10:26:41 +05:30
parent d34fdcb846
commit b65fbe8658
5 changed files with 639 additions and 297 deletions

View File

@@ -546,6 +546,26 @@ class Feedback(HorillaModel):
def __str__(self):
return f"{self.employee_id.employee_first_name} - {self.review_cycle}"
def requested_employees(self):
manager = self.manager_id
colleagues = self.colleague_id.all()
subordinates = self.subordinate_id.all()
owner = self.employee_id
employees = [employee for employee in subordinates]
for employee in colleagues:
if employee not in employees:
employees.append(employee)
if manager not in employees:
employees.append(manager)
if owner not in employees:
employees.append(owner)
return employees
class AnonymousFeedback(models.Model):
"""feedback model for creating feedback"""

View File

@@ -3,314 +3,432 @@
{% 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' : ''">
<section class="oh-wrapper oh-main__topbar">
<div class="oh-main__titlebar oh-main__titlebar--left oh-d-flex-column--resp oh-mb-3--small">
<h1 class="oh-main__titlebar-title fw-bold">{% trans "Feedback" %}: {{feedback.review_cycle}}</h1>
<div class="d-flex align-items-center mt-3">
<div class="oh-profile oh-profile--md" title="Owner">
<div class="oh-profile__avatar mr-1">
<img src="{{feedback.employee_id.get_avatar}}" class="oh-profile__image"
alt="." />
</div>
<span class="oh-profile__name oh-text--dark">{{feedback.employee_id}}</span>
</div>
<select id="status" class="oh-select oh-select--sm ms-3" name="feedback_status" title="Status"
hx-post="{%url 'feedback-detailed-view-status' id=feedback.id %}"
hx-trigger="change" hx-target="#message">
<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 class="oh-wrapper mb-2">
<div class="oh-card">
<div class="oh-main__titlebar oh-d-flex-column--resp oh-mb-3--small">
<h1 class="oh-main__titlebar-title fw-bold">{% trans "Feedback" %}: {{feedback}}</h1>
</div>
</div>
<!-- checking userlevel -->
{% if perms.pms.delete_feedback or request.user|filtersubordinates %}
<div class="oh-main__titlebar oh-main__titlebar--right">
<div class="oh-btn-group m-2">
<div class="oh-btn-group" >
<form action="{% url 'feedback-archive' id=feedback.id %}" method="post" onsubmit="return confirm('{% trans "Do you want archive this Feedback ?" %}')" >
<button class="oh-btn w-100 " title="{% trans 'Archive' %}" style="background-color: white;!important">
{% csrf_token %}
<ion-icon name="archive-sharp" type="submit"></ion-icon>
</button>
</form>
{% if perms.pms.delete_feedback %}
<form action="{% url 'feedback-delete' id=feedback.id %}" method="post" onsubmit="return confirm('{% trans "Do you want Delete this Feedback ?" %}')">
{% csrf_token %}
<button class="oh-btn oh-btn--danger-outline w-100" title="{% trans 'Delete' %}" style="background-color: white;!important">
<ion-icon name="trash-outline" role="img" class="md hydrated" aria-label="trash outline"></ion-icon>
</button>
</form>
<div class="align-items-center d-flex justify-content-between">
<div class="oh-profile oh-profile--md" title="Owner">
<span class="mr-2" style="font-size:15px;">{% trans "Owner: " %}</span>
<div class="oh-profile__avatar mr-1">
<img src="{{feedback.employee_id.get_avatar}}" class="oh-profile__image"
alt="." />
</div>
<span class="oh-profile__name oh-text--dark">{{feedback.employee_id}}</span>
</div>
{% if perms.pms.delete_feedback or request.user|filtersubordinates %}
<div class="oh-main__titlebar oh-main__titlebar--right justify-content-end">
<select id="status" class="oh-select oh-select--sm ms-3" name="feedback_status" title="Status"
hx-post="{%url 'feedback-detailed-view-status' id=feedback.id %}"
hx-trigger="change" hx-target="#message">
<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 class="oh-btn-group m-2">
<form action="{% url 'feedback-archive' id=feedback.id %}" method="post" onsubmit="return confirm('{% trans "Do you want archive this Feedback ?" %}')" >
<button class="oh-btn w-100 " title="{% trans 'Archive' %}" style="background-color: white;!important">
{% csrf_token %}
<ion-icon name="archive-sharp" type="submit"></ion-icon>
</button>
</form>
{% if perms.pms.delete_feedback %}
<form action="{% url 'feedback-delete' id=feedback.id %}" method="post" onsubmit="return confirm('{% trans "Do you want Delete this Feedback ?" %}')">
{% csrf_token %}
<button class="oh-btn oh-btn--danger-outline w-100" title="{% trans 'Delete' %}" style="background-color: white;!important">
<ion-icon name="trash-outline" role="img" class="md hydrated" aria-label="trash outline"></ion-icon>
</button>
</form>
{% endif %}
</div>
</div>
{% endif %}
</div>
<div >
<div class="align-items-center d-flex">
<span class="mr-2" style="font-size:15px;">{% trans "Due on: " %}</span>
<span class="d-flex justify-content-between">{{feedback.end_date}}</span>
<span class='d-flex justify-content-between align-items-center ml-2'
>
<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>
</span>
</div>
<div class="align-items-center d-flex">
<span class="mr-2" style="font-size:15px;">{% trans "Answered employees: " %}</span>
<div class="d-flex justify-content-between custom-scroll">
<div class="avatars" id="avatarsContainer">
{% for employee in employee_statics.yes %}
<a
href="{% url 'employee-view-individual' employee.id %}"
class="avatars__item"
title="{{employee}}"
><img class="avatar" src="{{employee.get_avatar}}" alt=""
/></a>
{% endfor %}
</div>
</div>
</div>
<div class="align-items-center d-flex">
<span class="mr-2" style="font-size:15px;" >{% trans "Employees not answerd yet: " %}</span>
<div class="d-flex justify-content-between custom-scroll">
<div class="avatars" id="avatarsContainer">
{% for employee in employee_statics.no %}
<a
href="{% url 'employee-view-individual' employee.id %}"
class="avatars__item"
title="{{employee}}"
><img class="avatar" src="{{employee.get_avatar}}" alt=""
/></a>
{% endfor %}
</div>
</div>
</div>
</div>
<!-- checking userlevel -->
</div>
{% endif %}
</section>
</div>
<div class="oh-wrapper mb-2">
<div class="oh-card p-4">
{% if perms.pms.change_feedback and not feedback_started %}
<div class="d-flex flex-row-reverse">
<button
class="oh-btn oh-btn--x-small d-flex align-items-center ms-2 "
data-toggle="oh-modal-toggle"
data-target="#feedbackModalPopup"
hx-get="{%url 'feedback-update' id=feedback.id %}"
hx-target="#feedbackModalTarget">
<ion-icon name="create-outline" class="me-1" ></ion-icon>
{% trans "Edit" %}
<div class="oh-tabs" >
<ul class="oh-tabs__tablist" >
<li class="oh-tabs__tab oh-tabs__tab--active" onclick="switchTab(event);" data-target="#feedback-answers">
{% trans "Feedback Answers" %}
</li>
<li class="oh-tabs__tab" onclick="switchTab(event);$('#feedback-overview-button').click()" data-target="#feedback-overview">
{% trans "Feedback Overview" %}
</li>
</ul>
<div class="oh-tabs__contents">
<!-- feddback answers -->
<div class="oh-tabs__content oh-tabs__content--active" id="feedback-answers">
<div class="oh-card p-4">
{% if perms.pms.change_feedback and not feedback_started %}
<div class="d-flex flex-row-reverse">
<button
class="oh-btn oh-btn--x-small d-flex align-items-center ms-2 "
data-toggle="oh-modal-toggle"
data-target="#feedbackModalPopup"
hx-get="{%url 'feedback-update' id=feedback.id %}"
hx-target="#feedbackModalTarget">
<ion-icon name="create-outline" class="me-1" ></ion-icon>
{% trans "Edit" %}
</button>
</div>
{% endif %}
<div class="row">
<div class="col-12 col-sm-12 col-md-12 col-lg-12">
<div class="m-2">
<div class="oh-card__body">
<div class="oh-sticky-table">
<div class="oh-sticky-table__table">
<div class="oh-sticky-table__thead">
<div class="oh-sticky-table__tr">
<div class="oh-sticky-table__th">{% trans "Employee" %}</div>
<div class="oh-sticky-table__th">{% trans "Status" %}</div>
<div class="oh-sticky-table__th"></div>
</div>
</div>
<div class="oh-sticky-table__tbody">
<div class="oh-sticky-table__tr">
<div class="oh-sticky-table__sd">
<ul class="oh-sticky-table___profile-list">
<li class="oh-sticky-table__profile-item">
<div class="oh-profile oh-profile--md">
<div class="oh-profile__avatar mr-1">
<img src="{{feedback.employee_id.get_avatar}}"
class="oh-profile__image" alt="{{feedback.employee_id}}" />
</div>
<span class="oh-profile__name oh-text--dark"> {{feedback.employee_id}}</span>
</div>
</li>
</ul>
</div>
<div class="oh-sticky-table__td">
<div class="d-flex align-items-center">
<span class=""></span><span class="feedback-status" x-data-feedback-id="{{feedback.id}}" x-data-employee-id="{{feedback.employee_id.id}}"> </span>
</div>
</div>
<div class="oh-sticky-table__td"><button
class="oh-btn oh-btn--secondary 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>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- manager section -->
<div class="row">
<div class="col-12 col-sm-12 col-md-12 col-lg-12">
<div class="m-2">
<div class="oh-card__body">
<div class="oh-sticky-table">
<div class="oh-sticky-table__table">
<div class="oh-sticky-table__thead">
<div class="oh-sticky-table__tr">
<div class="oh-sticky-table__th">{% trans "Manager" %}</div>
<div class="oh-sticky-table__th">{% trans "Status" %}</div>
<div class="oh-sticky-table__th"></div>
</div>
</div>
<div class="oh-sticky-table__tbody">
<div class="oh-sticky-table__tr">
<div class="oh-sticky-table__sd">
<ul class="oh-sticky-table___profile-list">
<li class="oh-sticky-table__profile-item">
<div class="oh-profile oh-profile--md">
<div class="oh-profile__avatar mr-1">
<img src="{{feedback.manager_id.get_avatar}}"
class="oh-profile__image" alt="{{feedback.employee_id}}" />
</div>
<span class="oh-profile__name oh-text--dark"> {{feedback.manager_id}}</span>
</div>
</li>
</ul>
</div>
<div class="oh-sticky-table__td">
<div class="d-flex align-items-center">
<span class=""></span><span class="feedback-status" x-data-feedback-id="{{feedback.id}}" x-data-employee-id="{{feedback.manager_id.id}}"></span>
</div>
</div>
<div class="oh-sticky-table__td"><button
class="oh-btn oh-btn--secondary 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></div>
</div>
<!-- manager answer off canvas -->
<div class="oh-activity-sidebar" id="managerAnswer">
<div class="oh-activity-sidebar__header">
<ion-icon name="chevron-back-outline"
class="oh-activity-sidebar__header-icon me-2 oh-activity-sidebar__close"
data-target="#managerAnswer"></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">
{% for answer in manager_answers %}
{% include 'feedback/feedback_detailed_view_answer.html' %}
{%endfor %}
</ol>
</div>
</div>
<!-- endof manager answer off canvas -->
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- subordinate section -->
<div class="row">
<div class="col-12 col-sm-12 col-md-12 col-lg-12">
<div class="m-2">
<div class="oh-card__body">
<div class="oh-sticky-table">
<div class="oh-sticky-table__table">
<div class="oh-sticky-table__thead">
<div class="oh-sticky-table__tr">
<div class="oh-sticky-table__th">{% trans "Subordinates" %}</div>
<div class="oh-sticky-table__th">{% trans "Status" %}</div>
<div class="oh-sticky-table__th"></div>
</div>
</div>
<div class="oh-sticky-table__tbody">
{% for employee in feedback.subordinate_id.all %}
<div class="oh-sticky-table__tr">
<div class="oh-sticky-table__sd">
<ul class="oh-sticky-table___profile-list">
<li class="oh-sticky-table__profile-item">
<div class="oh-profile oh-profile--md">
<div class="oh-profile__avatar mr-1">
<img src="{{employee.get_avatar}}"
class="oh-profile__image" alt="" />
</div>
<span class="oh-profile__name oh-text--dark"> {{employee}}</span>
</div>
</li>
</ul>
</div>
<div class="oh-sticky-table__td">
<div class="d-flex align-items-center">
<span class=""></span ><span class="feedback-status" x-data-feedback-id="{{feedback.id}}" x-data-employee-id="{{employee.id}}"></span>
</div>
</div>
<div class="oh-sticky-table__td"><button
class="oh-btn oh-btn--secondary 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></div>
</div>
{% endfor %}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- end of subordinate section -->
<!-- Colleague section -->
<div class="row">
<div class="col-12 col-sm-12 col-md-12 col-lg-12">
<div class="m-2">
<div class="oh-card__body">
<div class="oh-sticky-table">
<div class="oh-sticky-table__table">
<div class="oh-sticky-table__thead">
<div class="oh-sticky-table__tr">
<div class="oh-sticky-table__th">{% trans "Colleague" %}</div>
<div class="oh-sticky-table__th">{% trans "Status" %}</div>
<div class="oh-sticky-table__th"></div>
</div>
</div>
<div class="oh-sticky-table__tbody">
{% for employee in feedback.colleague_id.all %}
<div class="oh-sticky-table__tr">
<div class="oh-sticky-table__sd">
<ul class="oh-sticky-table___profile-list">
<li class="oh-sticky-table__profile-item">
<div class="oh-profile oh-profile--md">
<div class="oh-profile__avatar mr-1">
<img src="{{employee.get_avatar}}"
class="oh-profile__image" alt="" />
</div>
<span class="oh-profile__name oh-text--dark"> {{employee}}</span>
</div>
</li>
</ul>
</div>
<div class="oh-sticky-table__td">
<div class="d-flex align-items-center">
<span class=""></span><span class="feedback-status" x-data-feedback-id="{{feedback.id}}" x-data-employee-id="{{employee.id}}"></span>
</div>
</div>
<div class="oh-sticky-table__td"><button
class="oh-btn oh-btn--secondary 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></div>
</div>
{% endfor %}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- endof colleague section -->
</div>
<div class="oh-tabs__content" id="feedback-overview">
<div id="feedback_overview_div">
<button hx-get="{% url 'get-feedback-overview' feedback.id %}"
hx-target="#feedback-overview" id="feedback-overview-button" hidden>
</button>
</div>
{% endif %}
<div class="row">
<div class="col-12 col-sm-12 col-md-12 col-lg-12">
<div class="p-2 m-2">
<div class="oh-card__body">
<div class="oh-sticky-table">
<div class="oh-sticky-table__table">
<div class="oh-sticky-table__thead">
<div class="oh-sticky-table__tr">
<div class="oh-sticky-table__th">{% trans "Employee" %}</div>
<div class="oh-sticky-table__th">{% trans "Status" %}</div>
<div class="oh-sticky-table__th">{% trans "Due" %}</div>
<div class="oh-sticky-table__th"></div>
</div>
</div>
<div class="oh-sticky-table__tbody">
<div class="oh-sticky-table__tr">
<div class="oh-sticky-table__sd">
<ul class="oh-sticky-table___profile-list">
<li class="oh-sticky-table__profile-item">
<div class="oh-profile oh-profile--md">
<div class="oh-profile__avatar mr-1">
<img src="{{feedback.employee_id.get_avatar}}"
class="oh-profile__image" alt="{{feedback.employee_id}}" />
</div>
<span class="oh-profile__name oh-text--dark"> {{feedback.employee_id}}</span>
</div>
</li>
</ul>
</div>
<div class="oh-sticky-table__td">
<div class="d-flex align-items-center">
<span class=""></span><span class="feedback-status" x-data-feedback-id="{{feedback.id}}" x-data-employee-id="{{feedback.employee_id.id}}"> </span>
</div>
</div>
<div class="oh-sticky-table__td">
<div class="d-flex align-items-center">
{{ current_date|timesince:feedback.end_date }}
</div>
</div>
<div class="oh-sticky-table__td"><button
class="oh-btn oh-btn--secondary 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>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- manager section -->
<div class="row">
<div class="col-12 col-sm-12 col-md-12 col-lg-12">
<div class="p-2 m-2">
<div class="oh-card__body">
<div class="oh-sticky-table">
<div class="oh-sticky-table__table">
<div class="oh-sticky-table__thead">
<div class="oh-sticky-table__tr">
<div class="oh-sticky-table__th">{% trans "Manager" %}</div>
<div class="oh-sticky-table__th">{% trans "Status" %}</div>
<div class="oh-sticky-table__th">{% trans "Due" %}</div>
<div class="oh-sticky-table__th"></div>
</div>
</div>
<div class="oh-sticky-table__tbody">
<div class="oh-sticky-table__tr">
<div class="oh-sticky-table__sd">
<ul class="oh-sticky-table___profile-list">
<li class="oh-sticky-table__profile-item">
<div class="oh-profile oh-profile--md">
<div class="oh-profile__avatar mr-1">
<img src="{{feedback.manager_id.get_avatar}}"
class="oh-profile__image" alt="{{feedback.employee_id}}" />
</div>
<span class="oh-profile__name oh-text--dark"> {{feedback.manager_id}}</span>
</div>
</li>
</ul>
</div>
<div class="oh-sticky-table__td">
<div class="d-flex align-items-center">
<span class=""></span><span class="feedback-status" x-data-feedback-id="{{feedback.id}}" x-data-employee-id="{{feedback.manager_id.id}}"></span>
</div>
</div>
<div class="oh-sticky-table__td">
<div class="d-flex align-items-center">
{{ current_date|timesince:feedback.end_date }}
</div>
</div>
<div class="oh-sticky-table__td"><button
class="oh-btn oh-btn--secondary 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></div>
</div>
<!-- manager answer off canvas -->
<div class="oh-activity-sidebar" id="managerAnswer">
<div class="oh-activity-sidebar__header">
<ion-icon name="chevron-back-outline"
class="oh-activity-sidebar__header-icon me-2 oh-activity-sidebar__close"
data-target="#managerAnswer"></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">
{% for answer in manager_answers %}
{% include 'feedback/feedback_detailed_view_answer.html' %}
{%endfor %}
</ol>
</div>
</div>
<!-- endof manager answer off canvas -->
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- subordinate section -->
<div class="row">
<div class="col-12 col-sm-12 col-md-12 col-lg-12">
<div class="p-2 m-2">
<div class="oh-card__body">
<div class="oh-sticky-table">
<div class="oh-sticky-table__table">
<div class="oh-sticky-table__thead">
<div class="oh-sticky-table__tr">
<div class="oh-sticky-table__th">{% trans "Subordinates" %}</div>
<div class="oh-sticky-table__th">{% trans "Status" %}</div>
<div class="oh-sticky-table__th">{% trans "Due" %}</div>
<div class="oh-sticky-table__th"></div>
</div>
</div>
<div class="oh-sticky-table__tbody">
{% for employee in feedback.subordinate_id.all %}
<div class="oh-sticky-table__tr">
<div class="oh-sticky-table__sd">
<ul class="oh-sticky-table___profile-list">
<li class="oh-sticky-table__profile-item">
<div class="oh-profile oh-profile--md">
<div class="oh-profile__avatar mr-1">
<img src="{{employee.get_avatar}}"
class="oh-profile__image" alt="" />
</div>
<span class="oh-profile__name oh-text--dark"> {{employee}}</span>
</div>
</li>
</ul>
</div>
<div class="oh-sticky-table__td">
<div class="d-flex align-items-center">
<span class=""></span ><span class="feedback-status" x-data-feedback-id="{{feedback.id}}" x-data-employee-id="{{employee.id}}"></span>
</div>
</div>
<div class="oh-sticky-table__td">
<div class="d-flex align-items-center">
{{ current_date|timesince:feedback.end_date }}
</div>
</div>
<div class="oh-sticky-table__td"><button
class="oh-btn oh-btn--secondary 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></div>
</div>
{% endfor %}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- end of subordinate section -->
<!-- Colleague section -->
<div class="row">
<div class="col-12 col-sm-12 col-md-12 col-lg-12">
<div class="p-2 m-2">
<div class="oh-card__body">
<div class="oh-sticky-table">
<div class="oh-sticky-table__table">
<div class="oh-sticky-table__thead">
<div class="oh-sticky-table__tr">
<div class="oh-sticky-table__th">{% trans "Colleague" %}</div>
<div class="oh-sticky-table__th">{% trans "Status" %}</div>
<div class="oh-sticky-table__th">{% trans "Due" %}</div>
<div class="oh-sticky-table__th"></div>
</div>
</div>
<div class="oh-sticky-table__tbody">
{% for employee in feedback.colleague_id.all %}
<div class="oh-sticky-table__tr">
<div class="oh-sticky-table__sd">
<ul class="oh-sticky-table___profile-list">
<li class="oh-sticky-table__profile-item">
<div class="oh-profile oh-profile--md">
<div class="oh-profile__avatar mr-1">
<img src="{{employee.get_avatar}}"
class="oh-profile__image" alt="" />
</div>
<span class="oh-profile__name oh-text--dark"> {{employee}}</span>
</div>
</li>
</ul>
</div>
<div class="oh-sticky-table__td">
<div class="d-flex align-items-center">
<span class=""></span><span class="feedback-status" x-data-feedback-id="{{feedback.id}}" x-data-employee-id="{{employee.id}}"></span>
</div>
</div>
<div class="oh-sticky-table__td">
<div class="d-flex align-items-center">
{{feedback.end_date|timeuntil}}
</div>
</div>
<div class="oh-sticky-table__td"><button
class="oh-btn oh-btn--secondary 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></div>
</div>
{% endfor %}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- endof colleague section -->
</div>
</main>
<!-- answer off canvas -->

View File

@@ -0,0 +1,155 @@
{% load i18n %}
<div class="oh-card">
<div class="oh-accordion-meta">
{% for question,answers in feedback_overview.items %}
<div class="oh-accordion-meta__item">
<div class="oh-accordion-meta__header" onclick='$(this).toggleClass("oh-accordion-meta__header--show");'>
<span class="oh-accordion-meta__title pt-3 pb-3">
<div class="oh-tabs__input-badge-container">
<span
class="oh-badge oh-badge--round mr-1"
>
{{question}}
</span>
</div>
</span>
</div>
<div class="oh-accordion-meta__body d-none">
<div class="oh-sticky-table oh-sticky-table--no-overflow">
<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">{% trans "Employee" %}</div>
<div class="oh-sticky-table__th">{% trans "Answer" %}</div>
</div>
</div>
<div class="oh-sticky-table__tbody">
{% for answer in answers %}
{% for key,value in answer.items %}
<div class="oh-sticky-table__tr" draggable="true">
<div class="oh-sticky-table__td">
<div class="oh-profile oh-profile--md">
<div class="oh-profile__avatar mr-1">
<img
src="{{key.get_avatar}}"
class="oh-profile__image"
alt=""
/>
</div>
<span class="oh-profile__name oh-text--dark">{{key}}</span>
</div>
</div>
<div class="oh-sticky-table__td">
{% if value.1.type == '1' %}
<span class="oh-activity-sidebar__a">{{ value.0.answer}}</span>
{% endif %}
{% if value.1.type == '2' %}
<div class="d-block mb-0">
<div class="oh-rate">
<input type="radio" id="star5" value="5" disabled {% if value.0.answer == '5' %} checked {% endif %} />
<label for="star5" title="5 Stars">5 {% trans "Stars" %}</label>
<input type="radio" id="star4" value="4" disabled {% if value.0.answer == '4' %} checked {% endif %} />
<label for="star4" title="4 Stars">4 {% trans "Stars" %}</label>
<input type="radio" id="star3" value="3" disabled {% if value.0.answer == '3' %} checked {% endif %} />
<label for="star3" title="3 Stars">3 {% trans "Stars" %}</label>
<input type="radio" id="star2" value="2" disabled {% if value.0.answer == '2' %} checked {% endif %} />
<label for="star2" title="2 Stars">2 {% trans "Stars" %}</label>
<input type="radio" id="star1" value="1" disabled {% if value.0.answer == '1' %} checked {% endif %} />
<label for="star1" title="1 Star">1 {% trans "Star" %}</label>
</div>
</div>
{% endif %}
{% if 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>
{% endif %}
{% if value.1.type == '4' %}
<div class="d-block">
<label class="oh-label" for="answer1"> {{value.0.answer}}</label>
</div>
{% endif %}
{% if value.1.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 ">
{{value.0.answer}}
</div>
</div>
</div>
{% endif %}
</li>
</div>
</div>
{% endfor %}
{% endfor %}
</div>
</div>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
<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>

View File

@@ -167,6 +167,11 @@ urlpatterns = [
views.feedback_detailed_view_status,
name="feedback-detailed-view-status",
),
path(
"get-feedback-overview/<int:obj_id>",
views.get_feedback_overview,
name="get-feedback-overview",
),
path("feedback-status", views.feedback_status, name="feedback-status"),
path(
"question-creation/<int:id>", views.question_creation, name="question-creation"

View File

@@ -1782,12 +1782,23 @@ def feedback_detailed_view(request, id, **kwargs):
)
if is_have_perm:
feedback_started = Answer.objects.filter(feedback_id=id)
current_date = datetime.datetime.now()
employees = feedback.requested_employees()
yes = []
no = []
for employee in employees:
if Answer.objects.filter(
feedback_id=feedback, employee_id=employee
).exists():
yes.append(employee)
else:
no.append(employee)
employee_statics = {"yes": yes, "no": no}
context = {
"feedback": feedback,
"feedback_started": feedback_started,
"feedback_status": Feedback.STATUS_CHOICES,
"current_date": current_date,
"employee_statics": employee_statics,
"today": datetime.datetime.today().date(),
}
return render(request, "feedback/feedback_detailed_view.html", context)
else:
@@ -2026,6 +2037,39 @@ def feedback_detailed_view_status(request, id):
return render(request, "message.html")
@login_required
def get_feedback_overview(request, obj_id):
"""
overview of feedback
"""
feedback = Feedback.objects.filter(id=obj_id).first() if obj_id else None
if feedback and check_permission_feedback_detailed_view(
request, feedback, perm="pms.view_feedback"
):
question_template = feedback.question_template_id
questions = question_template.question.all()
feedback_answers = feedback.feedback_answer.all()
feedback_overview = {}
for question in questions:
answer_list = []
for answer in feedback_answers:
if answer.question_id == question:
answer_list.append(
{
answer.employee_id: [
answer.answer,
{"type": answer.question_id.question_type},
]
}
)
feedback_overview[question] = answer_list
return render(
request,
"feedback/feedback_overview.html",
context={"feedback_overview": feedback_overview},
)
@login_required
def feedback_archive(request, id):
"""