[UPDT] HELPDESK: Updated the ticket detailed, list, card views and its functions
This commit is contained in:
@@ -3,6 +3,7 @@ from django.contrib import admin
|
||||
from helpdesk.models import (
|
||||
FAQ,
|
||||
Attachment,
|
||||
ClaimRequest,
|
||||
Comment,
|
||||
DepartmentManager,
|
||||
FAQCategory,
|
||||
@@ -18,3 +19,4 @@ admin.site.register(FAQ)
|
||||
admin.site.register(FAQCategory)
|
||||
admin.site.register(Attachment)
|
||||
admin.site.register(DepartmentManager)
|
||||
admin.site.register(ClaimRequest)
|
||||
|
||||
@@ -27,7 +27,7 @@ from django import forms
|
||||
from django.template.loader import render_to_string
|
||||
|
||||
from base.forms import ModelForm
|
||||
from base.methods import is_reportingmanager
|
||||
from base.methods import filtersubordinatesemployeemodel, is_reportingmanager
|
||||
from base.models import Department, JobPosition
|
||||
from employee.forms import MultipleFileField
|
||||
from employee.models import Employee
|
||||
@@ -121,14 +121,30 @@ class TicketForm(ModelForm):
|
||||
self.fields["attachment"] = MultipleFileField(
|
||||
label="Attachements", required=False
|
||||
)
|
||||
self.fields["tags"].choices = list(self.fields["tags"].choices)
|
||||
self.fields["tags"].choices.append(("create_new_tag", "Create new tag"))
|
||||
self.fields["ticket_type"].choices = list(self.fields["ticket_type"].choices)
|
||||
request = getattr(horilla_middlewares._thread_locals, "request", None)
|
||||
if is_reportingmanager(request):
|
||||
instance = kwargs.get("instance")
|
||||
if instance:
|
||||
employee = instance.employee_id
|
||||
else:
|
||||
employee = request.user.employee_get
|
||||
# initialising employee queryset according to the user
|
||||
self.fields["employee_id"].queryset = filtersubordinatesemployeemodel(
|
||||
request, Employee.objects.filter(is_active=True), perm="helpdesk.add_ticket"
|
||||
) | Employee.objects.filter(employee_user_id=request.user)
|
||||
self.fields["employee_id"].initial = employee
|
||||
# appending dynamic create option according to user
|
||||
if is_reportingmanager(request) or request.user.has_perm(
|
||||
"helpdesk.add_tickettype"
|
||||
):
|
||||
self.fields["ticket_type"].choices = list(
|
||||
self.fields["ticket_type"].choices
|
||||
)
|
||||
self.fields["ticket_type"].choices.append(
|
||||
("create_new_ticket_type", "Create new ticket type")
|
||||
)
|
||||
if is_reportingmanager(request) or request.user.has_perm("base.add_tags"):
|
||||
self.fields["tags"].choices = list(self.fields["tags"].choices)
|
||||
self.fields["tags"].choices.append(("create_new_tag", "Create new tag"))
|
||||
|
||||
|
||||
class TicketTagForm(ModelForm):
|
||||
@@ -152,8 +168,10 @@ class TicketTagForm(ModelForm):
|
||||
If an instance is provided, sets the initial value for the form's .
|
||||
"""
|
||||
super().__init__(*args, **kwargs)
|
||||
self.fields["tags"].choices = list(self.fields["tags"].choices)
|
||||
self.fields["tags"].choices.append(("create_new_tag", "Create new tag"))
|
||||
request = getattr(horilla_middlewares._thread_locals, "request", None)
|
||||
if is_reportingmanager(request) or request.user.has_perm("base.add_tags"):
|
||||
self.fields["tags"].choices = list(self.fields["tags"].choices)
|
||||
self.fields["tags"].choices.append(("create_new_tag", "Create new tag"))
|
||||
|
||||
|
||||
class TicketRaisedOnForm(ModelForm):
|
||||
@@ -215,3 +233,21 @@ class DepartmentManagerCreateForm(ModelForm):
|
||||
class Meta:
|
||||
model = DepartmentManager
|
||||
fields = ["department", "manager"]
|
||||
widgets = {
|
||||
"department": forms.Select(
|
||||
attrs={
|
||||
"onchange": "getDepartmentEmployees($(this))",
|
||||
}
|
||||
),
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
if "instance" in kwargs:
|
||||
department = kwargs["instance"].department
|
||||
# Get the employees related to this department
|
||||
employees = department.employeeworkinformation_set.values_list(
|
||||
"employee_id", flat=True
|
||||
)
|
||||
# Set the manager field queryset to be those employees
|
||||
self.fields["manager"].queryset = Employee.objects.filter(id__in=employees)
|
||||
|
||||
21
helpdesk/methods.py
Normal file
21
helpdesk/methods.py
Normal file
@@ -0,0 +1,21 @@
|
||||
|
||||
|
||||
from helpdesk.models import DepartmentManager
|
||||
|
||||
|
||||
def is_department_manager(request,ticket):
|
||||
"""
|
||||
Method used to find the user is a department manger of given ticket
|
||||
"""
|
||||
user_emp = request.user.employee_get
|
||||
if ticket.assigning_type == "job_position":
|
||||
job_position = ticket.get_raised_on_object()
|
||||
department = job_position.department_id
|
||||
elif ticket.assigning_type == "department":
|
||||
department = ticket.get_raised_on_object()
|
||||
else:
|
||||
return False
|
||||
return DepartmentManager.objects.filter(
|
||||
manager = user_emp,
|
||||
department = department
|
||||
).exists()
|
||||
@@ -60,6 +60,14 @@ class DepartmentManager(HorillaModel):
|
||||
Company, null=True, editable=False, on_delete=models.PROTECT
|
||||
)
|
||||
|
||||
class Meta:
|
||||
unique_together = ("department", "manager")
|
||||
|
||||
def clean(self, *args, **kwargs):
|
||||
super().clean(*args, **kwargs)
|
||||
if not self.manager.get_department() == self.department:
|
||||
raise ValidationError(_(f"This employee is not from {self.department} ."))
|
||||
|
||||
|
||||
class TicketType(HorillaModel):
|
||||
title = models.CharField(max_length=100, unique=True)
|
||||
@@ -107,6 +115,9 @@ class Ticket(HorillaModel):
|
||||
related_company_field="employee_id__employee__work_info__company_id"
|
||||
)
|
||||
|
||||
class Meta:
|
||||
ordering = ["-created_date"]
|
||||
|
||||
def clean(self, *args, **kwargs):
|
||||
super().clean(*args, **kwargs)
|
||||
deadline = self.deadline
|
||||
@@ -144,6 +155,36 @@ class Ticket(HorillaModel):
|
||||
return get_diff(self)
|
||||
|
||||
|
||||
class ClaimRequest(HorillaModel):
|
||||
ticket_id = models.ForeignKey(
|
||||
Ticket,
|
||||
on_delete=models.CASCADE,
|
||||
null=True,
|
||||
blank=True,
|
||||
)
|
||||
employee_id = models.ForeignKey(
|
||||
Employee,
|
||||
on_delete=models.CASCADE,
|
||||
null=True,
|
||||
blank=True,
|
||||
)
|
||||
is_approved = models.BooleanField(default=False)
|
||||
is_rejected = models.BooleanField(default=False)
|
||||
|
||||
class Meta:
|
||||
unique_together = ("ticket_id", "employee_id")
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"{self.ticket_id}|{self.employee_id}"
|
||||
|
||||
def clean(self, *args, **kwargs):
|
||||
super().clean(*args, **kwargs)
|
||||
if not self.ticket_id:
|
||||
raise ValidationError({"ticket_id": _("This field is required.")})
|
||||
if not self.employee_id:
|
||||
raise ValidationError({"employee_id": _("This field is required.")})
|
||||
|
||||
|
||||
class Comment(HorillaModel):
|
||||
comment = models.TextField(null=True, blank=True)
|
||||
ticket = models.ForeignKey(Ticket, on_delete=models.CASCADE, related_name="comment")
|
||||
|
||||
@@ -64,4 +64,11 @@
|
||||
</div>
|
||||
<!-- end of edit modal -->
|
||||
<!-- end of modals -->
|
||||
<button id="getDepartmentEmployeesButton" hx-get="{% url "get-department-employee" %}" hx-target="#id_manager" hidden></button>
|
||||
<script>
|
||||
function getDepartmentEmployees(element){
|
||||
var dep_id = element.val()
|
||||
$('#getDepartmentEmployeesButton').attr('hx-vals', JSON.stringify({ dep_id: dep_id })).click();
|
||||
}
|
||||
</script>
|
||||
{% endblock settings %}
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
{% else %}
|
||||
hx-post="{% url 'department-manager-create' %}"
|
||||
{% endif %}
|
||||
hx-target="#deparmentManagersForm"
|
||||
hx-target="#deparmentManagersModal"
|
||||
hx-encoding="multipart/form-data"
|
||||
class="oh-profile-section"
|
||||
>
|
||||
|
||||
3
helpdesk/templates/helpdesk/methods.py
Normal file
3
helpdesk/templates/helpdesk/methods.py
Normal file
@@ -0,0 +1,3 @@
|
||||
|
||||
|
||||
def is_department_manager(request,ticket):
|
||||
File diff suppressed because it is too large
Load Diff
135
helpdesk/templates/helpdesk/ticket/ticket_claim_requests.html
Normal file
135
helpdesk/templates/helpdesk/ticket/ticket_claim_requests.html
Normal file
@@ -0,0 +1,135 @@
|
||||
{% load static %}{% load i18n %}
|
||||
<script>
|
||||
$("#reloadMessagesButton").click()
|
||||
</script>
|
||||
<div class="oh-card">
|
||||
<div class="oh-modal__dialog-header">
|
||||
<button
|
||||
type="button"
|
||||
class="oh-modal__close"
|
||||
data-dismiss="oh-modal"
|
||||
aria-label="Close"
|
||||
{% if refresh %} onclick="event.stopPropagation(); window.location.reload();" {% endif %}
|
||||
>
|
||||
<ion-icon name="close-outline"></ion-icon>
|
||||
</button>
|
||||
<span class="oh-modal__dialog-title ml-5">
|
||||
<h5>{% trans "Claim Requests" %}</h5>
|
||||
</span>
|
||||
</div>
|
||||
{% if claim_requests %}
|
||||
<div class="oh-sticky-table oh-sticky-table--no-overflow mb-5">
|
||||
<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 "Action" %}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="oh-sticky-table__tbody">
|
||||
{% for req in claim_requests %}
|
||||
<div
|
||||
class="oh-sticky-table__tr"
|
||||
>
|
||||
<div class="oh-sticky-table__sd">
|
||||
<div class="oh-profile oh-profile--md">
|
||||
<div
|
||||
class="oh-profile__avatar mr-1"
|
||||
>
|
||||
<img
|
||||
src="{{req.employee_id.get_avatar}}"
|
||||
class="oh-profile__image"
|
||||
alt=""
|
||||
/>
|
||||
</div>
|
||||
<span
|
||||
class="oh-profile__name oh-text--dark"
|
||||
>{{req.employee_id}}</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="oh-sticky-table__td">
|
||||
<div class="oh-btn-group">
|
||||
{% if not req.is_approved and not req.is_rejected %}
|
||||
<button
|
||||
class="oh-btn oh-btn--success w-100"
|
||||
data-toggle="oh-modal-toggle"
|
||||
data-target="#objectDetailsModal"
|
||||
hx-get="{% url 'approve-claim-request' req.id %}?approve=True"
|
||||
hx-target="#objectDetailsModalTarget"
|
||||
title="Approve request"
|
||||
>
|
||||
<ion-icon name="checkmark-outline"></ion-icon>
|
||||
</button>
|
||||
{% else %}
|
||||
<button
|
||||
class="oh-btn oh-btn--success w-100"
|
||||
disabled
|
||||
title="Approve request"
|
||||
>
|
||||
<ion-icon name="checkmark-outline"></ion-icon>
|
||||
</button>
|
||||
{% endif %}
|
||||
{% if not req.is_rejected %}
|
||||
<button
|
||||
class="oh-btn oh-btn--danger w-100"
|
||||
titile = "{% trans 'Reject' %}"
|
||||
data-toggle="oh-modal-toggle"
|
||||
data-target="#objectDetailsModal"
|
||||
hx-get="{% url 'approve-claim-request' req.id %}?approve=False"
|
||||
hx-target="#objectDetailsModalTarget"
|
||||
>
|
||||
<ion-icon name="close-outline"></ion-icon>
|
||||
</button>
|
||||
{% else %}
|
||||
<button
|
||||
class="oh-btn oh-btn--danger w-100"
|
||||
titile = "{% trans 'Reject' %}"
|
||||
disabled
|
||||
>
|
||||
<ion-icon name="close-outline"></ion-icon>
|
||||
</button>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div
|
||||
style="
|
||||
height: 70vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
"
|
||||
class=""
|
||||
>
|
||||
<div style="" class="oh-404">
|
||||
<img
|
||||
style="display: block; width: 150px; height: 150px; margin: 10px auto"
|
||||
src="{% static 'images/ui/ticket.png' %}"
|
||||
class="mb-4"
|
||||
alt=""
|
||||
/>
|
||||
<h3 style="font-size: 20px" class="oh-404__subtitle">
|
||||
{% trans "There are no claim requests at the moment." %}
|
||||
</h3>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
@@ -1,6 +1,6 @@
|
||||
{% extends 'index.html' %} {% load static %} {% load i18n %}
|
||||
{% load audit_filters %}
|
||||
{% load basefilters %}
|
||||
{% load basefilters %} {% load helpdeskfilters %}
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
@@ -12,10 +12,85 @@
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="oh-wrapper-main">
|
||||
{% comment %} <div id="sidebar"></div> {% endcomment %}
|
||||
{% block content %}
|
||||
|
||||
<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;
|
||||
}
|
||||
.horizontal-scroll{
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
overflow-x: auto;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="main">
|
||||
<!-- Navigation -->
|
||||
<div id="mainNav"></div>
|
||||
@@ -29,19 +104,38 @@
|
||||
<p class="oh-helpdesk__header-title">{{ticket.title}}</p>
|
||||
|
||||
<span class="helpdesk__card-value me-3">
|
||||
<select name="status_update" title='{% trans "Status" %}' class="oh-select" onchange="updateStatus()"
|
||||
style="
|
||||
width:190px;
|
||||
align-items: center;
|
||||
border: 1px solid #aaa;
|
||||
border-radius: 2px;
|
||||
background-color: #fff;
|
||||
">
|
||||
{% for status in ticket_status %}
|
||||
<option value="{{status.0}}" {% if status.0 == ticket.status %} selected {% endif %}>
|
||||
<span class="oh-dot oh-dot--small oh-dot--warning">{{status.1}}</span></option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
{% if perms.helpdesk.change_ticket or request.user.employee_get|is_department_manager:ticket or request.user.employee_get in ticket.assigned_to.all or request.user.employee_get == ticket.employee_id %}
|
||||
|
||||
<select name="status_update" title='{% trans "Status" %}' class="oh-select" onchange="updateStatus()"
|
||||
style="
|
||||
width:190px;
|
||||
align-items: center;
|
||||
border: 1px solid #aaa;
|
||||
border-radius: 2px;
|
||||
background-color: #fff;
|
||||
">
|
||||
{% for status in ticket_status %}
|
||||
<option value="{{status.0}}" {% if status.0 == ticket.status %} selected {% endif %}>
|
||||
<span class="oh-dot oh-dot--small oh-dot--warning">{{status.1}}</span></option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
{% else %}
|
||||
<select name="status_update" title='{% trans "Status" %}' class="oh-select"
|
||||
style="
|
||||
width:190px;
|
||||
align-items: center;
|
||||
border: 1px solid #aaa;
|
||||
border-radius: 2px;
|
||||
background-color: #fff;
|
||||
">
|
||||
{% for status in ticket_status %}
|
||||
{% if status.0 == ticket.status %}
|
||||
<option value="{{status.0}}" selected >
|
||||
<span class="oh-dot oh-dot--small oh-dot--warning">{{status.1}}</span></option>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</select>
|
||||
{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
<!-- Description Goes Here -->
|
||||
@@ -81,15 +175,13 @@
|
||||
<div class="oh-profile oh-profile--md">
|
||||
<div class="oh-profile__avatar mr-1">
|
||||
<img
|
||||
src="https://ui-avatars.com/api/?name={{item.comment.employee_id}}&background=random"
|
||||
src="{{item.comment.employee_id.get_avatar}}"
|
||||
class="oh-profile__image"
|
||||
alt="{{item.comment.employee_id}}" />
|
||||
</div>
|
||||
</div>
|
||||
<span class="oh-helpdesk__bubble-username">{{item.comment.employee_id}}</span>
|
||||
{% comment %} <span class="oh-text--xs oh-badge oh-badge--info ms-2"
|
||||
>Private</span
|
||||
> {% endcomment %}
|
||||
|
||||
</div>
|
||||
<span class="oh-helpdesk__bubble-timestamp"
|
||||
>{{item.comment.date}}
|
||||
@@ -99,43 +191,40 @@
|
||||
<span class="oh-helpdesk__comment">
|
||||
{{item.comment.comment}}
|
||||
</span>
|
||||
{% if item.comment.comment_attachment.all %}
|
||||
{% for attachment in item.comment.comment_attachment.all %}
|
||||
<div class="oh-helpdesk_attached-items">
|
||||
<div class="oh-helpdesk_attached--content">
|
||||
{% with extension=attachment.file.name|lower|slice:"-4:" %}
|
||||
<li class="oh-helpdesk__document">
|
||||
<a href="{{ attachment.file.url }}" target="_blank">
|
||||
<div class="oh-helpdesk__icon">
|
||||
<span class="oh-file-icon
|
||||
{% if extension == '.pdf' %} oh-file-icon--pdf
|
||||
{% elif extension in '.jpg .jpeg .png .gif .svg' %} oh-file-icon--image
|
||||
{% elif extension in '.mp3 .wav .ogg' %} oh-file-icon--audio
|
||||
{% elif extension in '.doc .docx' %} oh-file-icon--word
|
||||
{% elif extension in '.xls .xlsx' %} oh-file-icon--excel
|
||||
{% elif extension in '.ppt .pptx' %} oh-file-icon--powerpoint
|
||||
{% elif extension in '.html' %} oh-file-icon--html
|
||||
{% else %} oh-file-icon--default
|
||||
{% endif %}">
|
||||
</span>
|
||||
</div>
|
||||
</a>
|
||||
<a href="{{ attachment.file.url }}" target="_blank">
|
||||
<span class="oh-helpdesk__filename">{{ attachment }}</span>
|
||||
</a>
|
||||
</li>
|
||||
{% endwith %}
|
||||
</div>
|
||||
<a href="{{attachment.file.url}}" target="_blank" >
|
||||
<span class="oh-helpdesk__filename" >{{attachment}}</span>
|
||||
</a>
|
||||
<button class="oh-user-panel__remove">
|
||||
<ion-icon name="close-outline" role="img" class="md hydrated"
|
||||
aria-label="close outline"></ion-icon>
|
||||
</button>
|
||||
<div class="oh-scrollable-container">
|
||||
<div class="oh-layout--grid-3 mt-2 mb-2 horizontal-scroll"
|
||||
>
|
||||
{% if item.comment.comment_attachment.all %}
|
||||
{% for attachment in item.comment.comment_attachment.all %}
|
||||
{% with extension=attachment.file.name|lower|slice:"-4:" %}
|
||||
<a
|
||||
class ="me-2"
|
||||
data-toggle="oh-modal-toggle"
|
||||
data-target ="#viewFileModal"
|
||||
hx-target="#viewFile"
|
||||
hx-get="{% url 'view-ticket-document' attachment.id %}?ticket_id={{ticket.id}}"
|
||||
>
|
||||
<div class="oh-helpdesk__icon">
|
||||
<span class="oh-file-icon
|
||||
{% if extension == '.pdf' %} oh-file-icon--pdf
|
||||
{% elif extension in '.jpg .jpeg .png .gif .svg' %} oh-file-icon--image
|
||||
{% elif extension in '.mp3 .wav .ogg' %} oh-file-icon--audio
|
||||
{% elif extension in '.doc .docx' %} oh-file-icon--word
|
||||
{% elif extension in '.xls .xlsx' %} oh-file-icon--excel
|
||||
{% elif extension in '.ppt .pptx' %} oh-file-icon--powerpoint
|
||||
{% elif extension in '.html' %} oh-file-icon--html
|
||||
{% else %} oh-file-icon--default
|
||||
{% endif %}"
|
||||
title = "{{attachment}}"
|
||||
>
|
||||
</span>
|
||||
</div>
|
||||
</a>
|
||||
{% endwith %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -146,7 +235,7 @@
|
||||
<div class="oh-profile oh-profile--md">
|
||||
<div class="oh-profile__avatar mr-1">
|
||||
<img
|
||||
src="https://ui-avatars.com/api/?name={{item.comment.employee_id}}&background=random"
|
||||
src="{{item.comment.employee_id.get_avatar}}"
|
||||
class="oh-profile__image"
|
||||
alt="{{item.comment.employee_id}}" />
|
||||
</div>
|
||||
@@ -180,32 +269,40 @@
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{% if item.comment.comment_attachment.all %}
|
||||
{% for attachment in item.comment.comment_attachment.all %}
|
||||
{% with extension=attachment.file.name|lower|slice:"-4:" %}
|
||||
<li class="oh-helpdesk__document">
|
||||
<a href="{{ attachment.file.url }}" target="_blank">
|
||||
<div class="oh-helpdesk__icon">
|
||||
<span class="oh-file-icon
|
||||
{% if extension == '.pdf' %} oh-file-icon--pdf
|
||||
{% elif extension in '.jpg .jpeg .png .gif .svg' %} oh-file-icon--image
|
||||
{% elif extension in '.mp3 .wav .ogg' %} oh-file-icon--audio
|
||||
{% elif extension in '.doc .docx' %} oh-file-icon--word
|
||||
{% elif extension in '.xls .xlsx' %} oh-file-icon--excel
|
||||
{% elif extension in '.ppt .pptx' %} oh-file-icon--powerpoint
|
||||
{% elif extension in '.html' %} oh-file-icon--html
|
||||
{% else %} oh-file-icon--default
|
||||
{% endif %}">
|
||||
</span>
|
||||
</div>
|
||||
</a>
|
||||
<a href="{{ attachment.file.url }}" target="_blank">
|
||||
<span class="oh-helpdesk__filename">{{ attachment }}</span>
|
||||
</a>
|
||||
</li>
|
||||
{% endwith %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
<div class="oh-scrollable-container">
|
||||
<div class="oh-layout--grid-3 mt-2 mb-2 horizontal-scroll"
|
||||
>
|
||||
{% if item.comment.comment_attachment.all %}
|
||||
{% for attachment in item.comment.comment_attachment.all %}
|
||||
{% with extension=attachment.file.name|lower|slice:"-4:" %}
|
||||
<a
|
||||
class ="me-2"
|
||||
data-toggle="oh-modal-toggle"
|
||||
data-target ="#viewFileModal"
|
||||
hx-target="#viewFile"
|
||||
hx-get="{% url 'view-ticket-document' attachment.id %}"
|
||||
>
|
||||
<div class="oh-helpdesk__icon">
|
||||
<span class="oh-file-icon
|
||||
{% if extension == '.pdf' %} oh-file-icon--pdf
|
||||
{% elif extension in '.jpg .jpeg .png .gif .svg' %} oh-file-icon--image
|
||||
{% elif extension in '.mp3 .wav .ogg' %} oh-file-icon--audio
|
||||
{% elif extension in '.doc .docx' %} oh-file-icon--word
|
||||
{% elif extension in '.xls .xlsx' %} oh-file-icon--excel
|
||||
{% elif extension in '.ppt .pptx' %} oh-file-icon--powerpoint
|
||||
{% elif extension in '.html' %} oh-file-icon--html
|
||||
{% else %} oh-file-icon--default
|
||||
{% endif %}"
|
||||
title = "{{ attachment }}"
|
||||
>
|
||||
</span>
|
||||
</div>
|
||||
</a>
|
||||
{% endwith %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
@@ -270,16 +367,6 @@
|
||||
<div class="oh-helpdesk__card">
|
||||
<div class="oh-helpdesk__card-header d-flex justify-content-between align-items-center">
|
||||
<span class="oh-helpdesk__card-title">{% trans "Ticket Info" %}</span>
|
||||
{% if not ticket.assigned_to.all and request.user.employee_get != ticket.employee_id %}
|
||||
<a
|
||||
type="submit"
|
||||
href = "{% url 'claim-ticket' ticket.id %}"
|
||||
class="oh-btn oh-btn--info"
|
||||
title="{% trans 'claim' %}"
|
||||
>
|
||||
{% trans "Claim" %}
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="oh-helpdesk__card-body">
|
||||
<ul class="helpdesk__card-items">
|
||||
@@ -296,8 +383,23 @@
|
||||
<span class="helpdesk__card-value">{{ticket.created_date}}</span>
|
||||
</li>
|
||||
<li class="helpdesk__card-item">
|
||||
<form hx-swap="none" hx-post='{% url "update-priority" ticket.id %}' method="post">
|
||||
{% csrf_token %}
|
||||
{% if perms.helpdesk.change_ticket or request.user.employee_get|is_department_manager:ticket or request.user.employee_get in ticket.assigned_to.all or request.user.employee_get == ticket.employee_id %}
|
||||
<form hx-swap="none" hx-post='{% url "update-priority" ticket.id %}' method="post">
|
||||
{% csrf_token %}
|
||||
<div class="d-flex">
|
||||
<span class="helpdesk__card-label">{% trans "Priority" %} :</span>
|
||||
<div class="oh-rate" onclick="event.stopPropagation();$(this).parents().closest('form').find('button').click()">
|
||||
{% for i in "321" %}
|
||||
<input type="radio" id="star{{i}}{{ticket.id}}" name="rating" class="rating-radio" value="{{i}}" {% if rating == i %} checked {% endif %}/>
|
||||
<label for="star{{i}}{{ticket.id}}"
|
||||
{% if i == '1' %}title="{% trans 'Low' %}"{% elif i == '2' %}title="{% trans 'Medium' %}"{% else %}title="{% trans 'High' %}"{% endif %}></label>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<button type="submit" hidden="true" onclick="event.stopPropagation()"></button>
|
||||
<span id="rating-radio-error"></span>
|
||||
</div>
|
||||
</form>
|
||||
{% else %}
|
||||
<div class="d-flex">
|
||||
<span class="helpdesk__card-label">{% trans "Priority" %} :</span>
|
||||
<div class="oh-rate" onclick="event.stopPropagation();$(this).parents().closest('form').find('button').click()">
|
||||
@@ -307,10 +409,7 @@
|
||||
{% if i == '1' %}title="{% trans 'Low' %}"{% elif i == '2' %}title="{% trans 'Medium' %}"{% else %}title="{% trans 'High' %}"{% endif %}></label>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<button type="submit" hidden="true" onclick="event.stopPropagation()"></button>
|
||||
<span id="rating-radio-error"></span>
|
||||
</div>
|
||||
</form>
|
||||
{% endif %}
|
||||
</li>
|
||||
<li class="helpdesk__card-item">
|
||||
<span class="helpdesk__card-label">{% trans "Last activity:" %}</span>
|
||||
@@ -320,15 +419,20 @@
|
||||
{% endwith %}
|
||||
</span>
|
||||
</li>
|
||||
{% comment %} <li class="helpdesk__card-item">
|
||||
<span class="helpdesk__card-label">{% trans "Status:" %}</span>
|
||||
</li> {% endcomment %}
|
||||
</ul>
|
||||
<div class="helpdesk__card-footer">
|
||||
<span class="helpdesk__card-label">{% trans "Tags:" %}</span>
|
||||
{% if perms.helpdesk.change_ticket or request.user.employee_get == ticket.employee_id or request.user.employee_get|is_department_manager:ticket %}
|
||||
<div class="oh-helpdesk-selectbox">
|
||||
{{tag_form.tags}}
|
||||
</div>
|
||||
{% else %}
|
||||
<span class="helpdesk__card-value">
|
||||
{% for tag in ticket.tags.all %}
|
||||
{{tag}},
|
||||
{% endfor %}
|
||||
</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -343,15 +447,19 @@
|
||||
<div class="oh-helpdesk__subcard">
|
||||
<div class="oh-helpdesk__subcard-header">
|
||||
<span class="oh-helpdesk__subcard-title">{% trans "Forward to" %}</span>
|
||||
{% if perms.helpdesk.changeticket or request.user.employee_get == ticket.employee_id %}
|
||||
<a
|
||||
hx-get="{% url 'ticket-change-raised-on' ticket.id %}"
|
||||
data-target ="#addTagModal"
|
||||
hx-target="#addTagTarget"
|
||||
role="button"
|
||||
class="oh-link oh-link--secondary oh-text--xs"
|
||||
>{% trans "Change" %}</a
|
||||
>
|
||||
{% if perms.helpdesk.change_ticket or request.user.employee_get == ticket.employee_id %}
|
||||
<div class="oh-btn-group">
|
||||
<button
|
||||
class="oh-btn oh-btn--light-bkg p-3 w-100"
|
||||
hx-get="{% url 'ticket-change-raised-on' ticket.id %}"
|
||||
data-target ="#addTagModal"
|
||||
hx-target="#addTagTarget"
|
||||
role="button"
|
||||
title = "{% trans "Edit" %}"
|
||||
>
|
||||
<ion-icon name="create-outline"></ion-icon>
|
||||
</button>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="oh-helpdesk__subcard-body">
|
||||
@@ -364,39 +472,47 @@
|
||||
<div class="oh-helpdesk__subcard">
|
||||
<div class="oh-helpdesk__subcard-header">
|
||||
<span class="oh-helpdesk__subcard-title">{% trans "Assigned to" %}</span>
|
||||
{% if perms.helpdesk.changeticket %}
|
||||
<a
|
||||
hx-get="{% url 'ticket-change-assignees' ticket.id %}"
|
||||
data-target ="#addTagModal"
|
||||
hx-target="#addTagTarget"
|
||||
role="button"
|
||||
class="oh-link oh-link--secondary oh-text--xs"
|
||||
>{% trans "Change" %}</a
|
||||
>
|
||||
{% if perms.helpdesk.change_ticket or request.user.employee_get|is_department_manager:ticket %}
|
||||
<div class="oh-btn-group">
|
||||
|
||||
<button
|
||||
hx-get = "{% url "view-ticket-claim-request" ticket.id %}"
|
||||
hx-target="#objectDetailsModalTarget"
|
||||
data-toggle="oh-modal-toggle"
|
||||
data-target="#objectDetailsModal"
|
||||
class="oh-btn oh-btn--info p-3 w-100"
|
||||
title = "{% trans "Claim Requests" %}"
|
||||
>
|
||||
<ion-icon name="eye-outline"></ion-icon>
|
||||
|
||||
</button>
|
||||
<button
|
||||
class="oh-btn oh-btn--light-bkg p-3 w-100"
|
||||
hx-get="{% url 'ticket-change-assignees' ticket.id %}"
|
||||
data-target ="#addTagModal"
|
||||
hx-target="#addTagTarget"
|
||||
title="{% trans 'Edit' %}"
|
||||
|
||||
><ion-icon name="create-outline"></ion-icon>
|
||||
</button>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
{% for assignee in ticket.assigned_to.all %}
|
||||
<div class="oh-helpdesk__subcard-body">
|
||||
<ul class="oh-helpdesk__subcard-items">
|
||||
<li class="oh-helpdesk__subcard-item">
|
||||
<div class="oh-profile oh-profile--base">
|
||||
<div class="oh-profile__avatar mr-1">
|
||||
<img
|
||||
src="https://ui-avatars.com/api/?name={{assignee}}&background=random"
|
||||
class="oh-profile__image"
|
||||
alt="{{assignee}}" />
|
||||
</div>
|
||||
<div class="oh-profile__meta">
|
||||
<span class="oh-profile__name oh-text--dark"
|
||||
>{{assignee}}</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="align-items-center d-flex" style="min-height: 40px;">
|
||||
<div class="d-flex justify-content-between custom-scroll">
|
||||
<div class="avatars" id="avatarsContainer">
|
||||
{% for employee in ticket.assigned_to.all %}
|
||||
<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>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -406,13 +522,19 @@
|
||||
<div class="oh-helpdesk__card-header">
|
||||
<span class="oh-helpdesk__card-title">{% trans "Documents" %}</span>
|
||||
</div>
|
||||
<div class="oh-helpdesk__card-body">
|
||||
<ul class="oh-helpdesk__documents">
|
||||
<div class="oh-helpdesk__card-body oh-scrollable-container">
|
||||
<div class="oh-layout--grid-3 mt-2 mb-2 horizontal-scroll"
|
||||
>
|
||||
{% if attachments %}
|
||||
{% for attachment in attachments %}
|
||||
{% with extension=attachment.file.name|lower|slice:"-4:" %}
|
||||
<li class="oh-helpdesk__document">
|
||||
<a href="{{ attachment.file.url }}" target="_blank">
|
||||
<a
|
||||
class ="me-2"
|
||||
data-toggle="oh-modal-toggle"
|
||||
data-target ="#viewFileModal"
|
||||
hx-target="#viewFile"
|
||||
hx-get="{% url 'view-ticket-document' attachment.id %}"
|
||||
>
|
||||
<div class="oh-helpdesk__icon">
|
||||
<span class="oh-file-icon
|
||||
{% if extension == '.pdf' %} oh-file-icon--pdf
|
||||
@@ -423,18 +545,17 @@
|
||||
{% elif extension in '.ppt .pptx' %} oh-file-icon--powerpoint
|
||||
{% elif extension in '.html' %} oh-file-icon--html
|
||||
{% else %} oh-file-icon--default
|
||||
{% endif %}">
|
||||
{% endif %}"
|
||||
title = "{{ attachment }}"
|
||||
>
|
||||
</span>
|
||||
</div>
|
||||
</a>
|
||||
<a href="{{ attachment.file.url }}" target="_blank">
|
||||
<span class="oh-helpdesk__filename">{{ attachment }}</span>
|
||||
</a>
|
||||
</li>
|
||||
{% endwith %}
|
||||
{% endfor %}
|
||||
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- End of Document Card -->
|
||||
@@ -481,6 +602,31 @@
|
||||
</div>
|
||||
<!-- end of create tag modal. -->
|
||||
|
||||
<div
|
||||
class="oh-modal"
|
||||
id="viewFileModal"
|
||||
role="dialog"
|
||||
aria-labelledby="viewFileModal"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<div class="oh-modal__dialog custom-dialog">
|
||||
<div class="oh-modal__dialog-header">
|
||||
<span class="oh-modal__dialog-title" id="viewFileModalLabel"
|
||||
>{% trans "View File" %}</span
|
||||
>
|
||||
<button class="oh-modal__close" aria-label="Close">
|
||||
<ion-icon
|
||||
name="close-outline"
|
||||
role="img"
|
||||
class="md hydrated"
|
||||
aria-label="close outline"
|
||||
></ion-icon>
|
||||
</button>
|
||||
</div>
|
||||
<div class="oh-modal__dialog-body" id="viewFile"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Function to send rating via AJAX
|
||||
function sendRating(ratingValue) {
|
||||
|
||||
50
helpdesk/templates/helpdesk/ticket/ticket_document.html
Normal file
50
helpdesk/templates/helpdesk/ticket/ticket_document.html
Normal file
@@ -0,0 +1,50 @@
|
||||
{% load i18n %} {% load horillafilters %} {% load static %}
|
||||
<div class="d-flex justify-content-end">
|
||||
<div class="oh-btn-group mb-4">
|
||||
{% if document.file %}
|
||||
<a
|
||||
href="data:{{ content_type }};base64,{{ file_content|base64_encode }}"
|
||||
class="oh-btn oh-btn--info w-100"
|
||||
download="{{document.file}}"
|
||||
title="{% trans 'Download' %}"
|
||||
><ion-icon class="me-1" name="download-outline"></ion-icon
|
||||
></a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% if document.file %}
|
||||
<div class="modal-body">
|
||||
<!-- Display the file content based on the file type -->
|
||||
{% if file_extension == 'pdf' or file_extension == 'txt' or file_extension == 'docx' or file_extension == 'xlsx' %}
|
||||
<embed
|
||||
src="data:{{ content_type }};base64,{{ file_content|base64_encode }}"
|
||||
type="{{ content_type }}"
|
||||
width="100%"
|
||||
height="500px"
|
||||
/>
|
||||
{% elif file_extension == 'jpg' or file_extension == 'jpeg' or file_extension == 'png' or file_extension == 'webp' %}
|
||||
<div class="container">
|
||||
<img
|
||||
src="data:{{ content_type }};base64,{{ file_content|base64_encode }}"
|
||||
alt="File Preview"
|
||||
class="img-fluid"
|
||||
style="display: block; width: 100%;height: 500px;"
|
||||
/>
|
||||
</div>
|
||||
{% else %}
|
||||
<p>{% trans "File format not supported for preview." %}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="oh-not-found">
|
||||
<img
|
||||
style="width: 150px; height: 150px;"
|
||||
src="{% static 'images/ui/document.png' %}"
|
||||
class="oh-404__image mb-4"
|
||||
alt="Page not found. 404."
|
||||
/>
|
||||
<h3 class="oh-404__subtitle">
|
||||
{% trans "No Document to view." %}
|
||||
</h3>
|
||||
</div>
|
||||
{% endif %}
|
||||
@@ -1,16 +1,11 @@
|
||||
{% load i18n %}
|
||||
<!-- start of filter -->
|
||||
<form
|
||||
{% if request.GET.view == 'card' %}
|
||||
method="get"
|
||||
action=""
|
||||
{% else %}
|
||||
method="post"
|
||||
hx-get="{% url 'ticket-filter' %}?view={{view}}"
|
||||
hx-target="#ticket_list"
|
||||
{% endif %}
|
||||
id="filterForm"
|
||||
class="d-flex"
|
||||
onsubmit="event.preventDefault()"
|
||||
>
|
||||
{% csrf_token %}
|
||||
<div
|
||||
@@ -186,10 +181,10 @@
|
||||
</form>
|
||||
<!-- end of filter -->
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
{% comment %} $(document).ready(function () { {% endcomment %}
|
||||
|
||||
$("#id_field").on("change", function () {
|
||||
$(".filterButton")[0].click();
|
||||
});
|
||||
});
|
||||
{% comment %} }); {% endcomment %}
|
||||
</script>
|
||||
|
||||
139
helpdesk/templates/helpdesk/ticket/ticket_individual_view.html
Normal file
139
helpdesk/templates/helpdesk/ticket/ticket_individual_view.html
Normal file
@@ -0,0 +1,139 @@
|
||||
{% load static %} {% load i18n %}{% load helpdeskfilters %}
|
||||
|
||||
<div class="oh-modal__dialog-header">
|
||||
<span
|
||||
class="oh-modal__dialog-title"
|
||||
id="objectDetailsModalLabel"
|
||||
>
|
||||
{{ ticket }}
|
||||
</span>
|
||||
<button class="oh-modal__close" aria-label="Close">
|
||||
<button class="oh-modal__close"><ion-icon name="close-outline"></ion-icon></button>
|
||||
</button>
|
||||
</div>
|
||||
<div class="oh-modal__dialog-body">
|
||||
<a class="oh-timeoff-modal__profile-content pt-4" style="text-decoration:none;"
|
||||
href ="{% url 'employee-view-individual' ticket.employee_id.id %}">
|
||||
<div class="oh-profile mb-2">
|
||||
<div class="oh-profile__avatar">
|
||||
<img
|
||||
src="{{ticket.employee_id.get_avatar}}"
|
||||
class="oh-profile__image me-2"
|
||||
alt="Mary Magdalene"
|
||||
/>
|
||||
</div>
|
||||
<div class="oh-timeoff-modal__profile-info">
|
||||
<span class="oh-timeoff-modal__user fw-bold m-0"
|
||||
>{{ticket.employee_id.get_full_name}}</span
|
||||
>
|
||||
<span
|
||||
class="oh-timeoff-modal__user m-0"
|
||||
style="font-size: 18px; color: #4d4a4a"
|
||||
>
|
||||
{{ticket.employee_id.employee_work_info.department_id}} /
|
||||
{{ticket.employee_id.employee_work_info.job_position_id}}</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<div class="oh-modal__dialog-header pt-0 pb-0">
|
||||
<div class="oh-timeoff-modal__stats-container">
|
||||
<div class="oh-timeoff-modal__stat">
|
||||
<span class="oh-timeoff-modal__stat-title"
|
||||
>{% trans "Ticket type" %}
|
||||
</span>
|
||||
<span class="oh-timeoff-modal__stat-count"
|
||||
>{{ticket.ticket_type}}</span
|
||||
>
|
||||
</div>
|
||||
<div class="oh-timeoff-modal__stat">
|
||||
<span class="oh-timeoff-modal__stat-title"
|
||||
>{% trans "Forward to" %}</span
|
||||
>
|
||||
<span class="oh-timeoff-modal__stat-count"
|
||||
>{{ticket.get_raised_on}}</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="oh-timeoff-modal__stats-container mt-3">
|
||||
<div class="oh-timeoff-modal__stat">
|
||||
<span class="oh-timeoff-modal__stat-title"
|
||||
>{% trans "Dead line" %}
|
||||
</span>
|
||||
<span class="oh-timeoff-modal__stat-count dateformat_changer"
|
||||
>{{ticket.deadline}}</span
|
||||
>
|
||||
</div>
|
||||
<div class="oh-timeoff-modal__stat">
|
||||
<span class="oh-timeoff-modal__stat-title"
|
||||
>{% trans "Priority" %}
|
||||
</span>
|
||||
<div class="oh-rate">
|
||||
|
||||
{% if ticket.priority == 'low' %}
|
||||
<div class="d-flex">
|
||||
<div class="oh-rate">
|
||||
{% for i in "321" %}
|
||||
<input type="radio" id="star{{i}}{{ticket.id}}" name="rating" class="rating-radio" value="{{i}}" {% if '1' == i %} checked {% endif %}/>
|
||||
<label for="star{{i}}{{ticket.id}}"
|
||||
{% if i == '1' %}title="{% trans 'Low' %}"{% elif i == '2' %}title="{% trans 'Medium' %}"{% else %}title="{% trans 'High' %}"{% endif %}></label>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% elif ticket.priority == 'medium' %}
|
||||
<div class="d-flex">
|
||||
<div class="oh-rate">
|
||||
{% for i in "321" %}
|
||||
<input type="radio" id="star{{i}}{{ticket.id}}" name="rating" class="rating-radio" value="{{i}}" {% if '2' == i %} checked {% endif %}/>
|
||||
<label for="star{{i}}{{ticket.id}}"
|
||||
{% if i == '1' %}title="{% trans 'Low' %}"{% elif i == '2' %}title="{% trans 'Medium' %}"{% else %}title="{% trans 'High' %}"{% endif %}></label>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="d-flex">
|
||||
<div class="oh-rate">
|
||||
{% for i in "321" %}
|
||||
<input type="radio" id="star{{i}}{{ticket.id}}" name="rating" class="rating-radio" value="{{i}}" {% if '3' == i %} checked {% endif %}/>
|
||||
<label for="star{{i}}{{ticket.id}}"
|
||||
{% if i == '1' %}title="{% trans 'Low' %}"{% elif i == '2' %}title="{% trans 'Medium' %}"{% else %}title="{% trans 'High' %}"{% endif %}></label>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="oh-timeoff-modal__stats-container mt-3">
|
||||
<div class="oh-timeoff-modal__stat w-100">
|
||||
<span class="oh-timeoff-modal__stat-title">{% trans "Description" %}</span>
|
||||
<span class="oh-timeoff-modal__stat-count"
|
||||
>{{ticket.description}}</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class = "oh-modal__button-container text-center mt-3" onclick="event.stopPropagation()">
|
||||
<div class="oh-btn-group" style="border:none">
|
||||
{% if ticket|calim_request_exists:request.user.employee_get or request.user.employee_get in ticket.assigned_to.all %}
|
||||
<a
|
||||
href="#"
|
||||
class="oh-btn oh-btn--info w-100 oh-btn--disabled"
|
||||
title="{% trans 'Claim' %}"
|
||||
>
|
||||
<ion-icon name="checkmark-done-outline"></ion-icon>
|
||||
</a>
|
||||
{% else %}
|
||||
<a
|
||||
type="submit"
|
||||
href = "{% url 'claim-ticket' ticket.id %}"
|
||||
class="oh-btn oh-btn--info w-100"
|
||||
title="{% trans 'Claim' %}"
|
||||
>
|
||||
<ion-icon name="checkmark-done-outline"></ion-icon>
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -38,7 +38,6 @@
|
||||
|
||||
<!-- start of request view -->
|
||||
<div class="oh-wrapper" id="ticketContainer">
|
||||
{% if my_tickets or allocated_tickets or all_tickets %}
|
||||
<!-- start of Quick filters -->
|
||||
<div class="d-flex flex-row-reverse mb-2">
|
||||
<span
|
||||
@@ -148,29 +147,6 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- end of contents -->
|
||||
{% else %}
|
||||
<div
|
||||
style="
|
||||
height: 70vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
"
|
||||
class=""
|
||||
>
|
||||
<div style="" class="oh-404">
|
||||
<img
|
||||
style="display: block; width: 150px; height: 150px; margin: 10px auto"
|
||||
src="{% static 'images/ui/ticket.png' %}"
|
||||
class="mb-4"
|
||||
alt=""
|
||||
/>
|
||||
<h3 style="font-size: 20px" class="oh-404__subtitle">
|
||||
{% trans "There are no tickets at the moment." %}
|
||||
</h3>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<!-- end of request view -->
|
||||
|
||||
|
||||
0
helpdesk/templatetags/__init__.py
Normal file
0
helpdesk/templatetags/__init__.py
Normal file
30
helpdesk/templatetags/helpdeskfilters.py
Normal file
30
helpdesk/templatetags/helpdeskfilters.py
Normal file
@@ -0,0 +1,30 @@
|
||||
from django import template
|
||||
from django.template.defaultfilters import register
|
||||
|
||||
from helpdesk.models import ClaimRequest,DepartmentManager
|
||||
|
||||
register = template.Library()
|
||||
|
||||
@register.filter(name="calim_request_exists")
|
||||
def calim_request_exists(ticket,employee):
|
||||
return ClaimRequest.objects.filter(
|
||||
ticket_id = ticket,
|
||||
employee_id = employee
|
||||
).exists()
|
||||
|
||||
@register.filter(name="is_department_manager")
|
||||
def is_department_manager(employee,ticket):
|
||||
"""
|
||||
Check requested user is a department manger or not
|
||||
"""
|
||||
if ticket.assigning_type == "job_position":
|
||||
job_position = ticket.get_raised_on_object()
|
||||
department = job_position.department_id
|
||||
elif ticket.assigning_type == "department":
|
||||
department = ticket.get_raised_on_object()
|
||||
else:
|
||||
return False
|
||||
return DepartmentManager.objects.filter(
|
||||
manager = employee,
|
||||
department = department
|
||||
).exists()
|
||||
@@ -57,6 +57,16 @@ urlpatterns = [
|
||||
name="ticket-detail",
|
||||
kwargs={"model": Ticket},
|
||||
),
|
||||
path(
|
||||
"ticket-individual-view/<int:ticket_id>",
|
||||
views.ticket_individual_view,
|
||||
name="ticket-individual-view",
|
||||
),
|
||||
path(
|
||||
"view-ticket-claim-request/<int:ticket_id>",
|
||||
views.view_ticket_claim_request,
|
||||
name="view-ticket-claim-request",
|
||||
),
|
||||
path("ticket-change-tag", views.ticket_update_tag, name="ticket-change-tag"),
|
||||
path(
|
||||
"ticket-change-raised-on/<int:ticket_id>",
|
||||
@@ -70,6 +80,11 @@ urlpatterns = [
|
||||
),
|
||||
path("ticket-create-tag", views.create_tag, name="ticket-create-tag"),
|
||||
path("remove-tag", views.remove_tag, name="remove-tag"),
|
||||
path(
|
||||
"view-ticket-document/<int:doc_id>",
|
||||
views.view_ticket_document,
|
||||
name="view-ticket-document",
|
||||
),
|
||||
path("comment-create/<int:ticket_id>", views.comment_create, name="comment-create"),
|
||||
path("comment-edit/", views.comment_edit, name="comment-edit"),
|
||||
path(
|
||||
@@ -77,6 +92,11 @@ urlpatterns = [
|
||||
),
|
||||
path("get-raised-on", views.get_raised_on, name="get-raised-on"),
|
||||
path("claim-ticket/<int:id>", views.claim_ticket, name="claim-ticket"),
|
||||
path(
|
||||
"approve-claim-request/<int:req_id>",
|
||||
views.approve_claim_request,
|
||||
name="approve-claim-request",
|
||||
),
|
||||
path(
|
||||
"tickets-select-filter",
|
||||
views.tickets_select_filter,
|
||||
@@ -123,4 +143,9 @@ urlpatterns = [
|
||||
views.view_department_managers,
|
||||
name="department-manager-view",
|
||||
),
|
||||
path(
|
||||
"get-department-employee",
|
||||
views.get_department_employees,
|
||||
name="get-department-employee",
|
||||
),
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user