* [UPDT] BASE: Updated disciplinary action type model by adding abstract class * [UPDT] BASE: Updated abstract model class save method by fethcing request from thread local * [UPDT] LEAVE: Updated models in leave module by adding abstract class * [UPDT] LEAVE: Updated leave request model by adding abstract class * [UPDT] DASHBOARD: Floating quick action button rather than static template inside dashboard * [UPDT] Test database * [UPDT] ASSET: Updated models in asset app by adding abstract class HorillaModels * [UPDT] ASSET: Updated asset category form by adding exclude fields in class Meta * [FIX] ATTENDANCE: Attendance overtime permission wrong permission * [UPDT] Test Database
819 lines
36 KiB
HTML
819 lines
36 KiB
HTML
{% load i18n %} {% load i18n %} {% load static %} {% include 'filter_tags.html' %} {% load mathfilters %}
|
|
<div class="oh-tabs__contents" id="view-container">
|
|
<div class="oh-tabs__content" id="tab_1">
|
|
{% if my_tickets %}
|
|
<div class="oh-table_sticky--wrapper">
|
|
<div class="oh-sticky-dropdown--header">
|
|
<div class="oh-dropdown" x-data="{open: false}">
|
|
<button class="oh-sticky-dropdown_btn " @click="open = !open"><ion-icon name="ellipsis-vertical-sharp"
|
|
role="img" class="md hydrated" aria-label="ellipsis vertical sharp"></ion-icon></button>
|
|
<div class="oh-dropdown__menu oh-sticky-table_dropdown" x-show="open" @click.outside="open = false">
|
|
<ul class="oh-dropdown__items" id="MyTicketsCells">
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="my-ticket-table" data-table-name="my_ticket_table">
|
|
<!-- start of Sticky Table -->
|
|
<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" style="width: 10px">
|
|
<div class="centered-div">
|
|
<input
|
|
type="checkbox"
|
|
title='{% trans "Select All" %}'
|
|
class="oh-input oh-input__checkbox myTicketsAll"
|
|
id=""
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div class="oh-sticky-table__th">{% trans "Ticket Id" %}</div>
|
|
<div data-cell-index="1" data-cell-title='{% trans "Title" %}'
|
|
class="oh-sticky-table__th {% if request.sort_option.order == '-title' %}arrow-up {% elif request.sort_option.order == 'title' %}arrow-down {% else %}arrow-up-down {% endif %}" hx-target='#view-container' hx-get="{% url 'ticket-filter' %}?{{pd}}&sortby=title"
|
|
>{% trans "Title" %}</div>
|
|
<div data-cell-index="2" data-cell-title='{% trans "Owner" %}'
|
|
class="oh-sticky-table__th"
|
|
>{% trans "Owner" %}</div>
|
|
<div data-cell-index="3" data-cell-title='{% trans "Type" %}'
|
|
class="oh-sticky-table__th {% if request.sort_option.order == '-ticket_type__title' %}arrow-up {% elif request.sort_option.order == 'ticket_type__title' %}arrow-down {% else %}arrow-up-down {% endif %}" hx-target='#view-container' hx-get="{% url 'ticket-filter' %}?{{pd}}&sortby=ticket_type__title"
|
|
>{% trans "Type" %}</div>
|
|
<div data-cell-index="4" data-cell-title='{% trans "Forward to" %}' class="oh-sticky-table__th">{% trans "Forward to" %}</div>
|
|
<div data-cell-index="5" data-cell-title='{% trans "Assigned to" %}' class="oh-sticky-table__th">{% trans "Assigned to" %}</div>
|
|
<div data-cell-index="6" data-cell-title='{% trans "Status" %}' class="oh-sticky-table__th">{% trans "Status" %}</div>
|
|
<div data-cell-index="7" data-cell-title='{% trans "Priority" %}' class="oh-sticky-table__th">{% trans "Priority" %}</div>
|
|
<div data-cell-index="8" data-cell-title='{% trans "Tags" %}' class="oh-sticky-table__th">{% trans "Tags" %}</div>
|
|
<div class="oh-sticky-table__th oh-sticky-table__right">{% trans "Actions" %}</div>
|
|
</div>
|
|
</div>
|
|
<div class="oh-sticky-table__tbody">
|
|
{% for ticket in my_tickets %}
|
|
<div class="oh-sticky-table__tr" onclick="window.location.href = `{% url 'ticket-detail' ticket.id %}`" >
|
|
<div class="oh-sticky-table__sd
|
|
{% if ticket.status == 'new' %}row-status--blue
|
|
{% elif ticket.status == 'in_progress' %}row-status--orange
|
|
{% elif ticket.status == 'resolved' %}row-status--yellowgreen
|
|
{% elif ticket.status == 'on_hold' %}row-status--red
|
|
{% elif ticket.status == 'canceled' %}row-status--grey{% endif %}"
|
|
onclick="event.stopPropagation()"
|
|
>
|
|
<div class="centered-div">
|
|
<input
|
|
type="checkbox"
|
|
id="{{ticket.id}}"
|
|
onchange="highlightRow($(this))"
|
|
class="oh-input holiday-checkbox oh-input__checkbox my-tickets-row"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div class="oh-sticky-table__td">
|
|
<span class='d-flex justify-content-between align-items-center'
|
|
>
|
|
{{ticket.ticket_type.prefix}}{{ ticket.id|stringformat:"03d" }}
|
|
<span title = 'due {% if ticket.deadline == today %} today {% else %}in {{ticket.deadline|sub:today}}{% endif %}'>
|
|
<ion-icon
|
|
class="text-{% if ticket.deadline < today %}danger {% elif ticket.deadline == today %}warning {% else %}success{% endif %}"
|
|
name="time-sharp"
|
|
>
|
|
</ion-icon>
|
|
</span>
|
|
</span>
|
|
</div>
|
|
<div data-cell-index="1" class="oh-sticky-table__td">{{ticket.title}}</div>
|
|
<div data-cell-index="2" class="oh-sticky-table__td">{{ticket.employee_id}}</div>
|
|
<div data-cell-index="3" class="oh-sticky-table__td">{{ticket.ticket_type}}</div>
|
|
<div data-cell-index="4" class="oh-sticky-table__td">{{ticket.get_raised_on}}</div>
|
|
<div data-cell-index="5" class="oh-sticky-table__td">{{ticket.assigned_to.all|join:" , "}}</div>
|
|
<div data-cell-index="6" class="oh-sticky-table__td">{{ticket.get_status_display}}</div>
|
|
<div data-cell-index="7" class="oh-sticky-table__td">
|
|
{% if ticket.priority == 'high' %}
|
|
<img style="width:15%;" src="{% static 'images/ui/orange_star.png' %}"/>
|
|
<img style="width:15%;" src="{% static 'images/ui/orange_star.png' %}"/>
|
|
<img style="width:15%;" src="{% static 'images/ui/orange_star.png' %}"/>
|
|
{% elif ticket.priority == 'medium' %}
|
|
<img style="width:15%;" src="{% static 'images/ui/orange_star.png' %}"/>
|
|
<img style="width:15%;" src="{% static 'images/ui/orange_star.png' %}"/>
|
|
<img style="width:15%;" src="{% static 'images/ui/star.png' %}"/>
|
|
{% elif ticket.priority == 'low' %}
|
|
<img style="width:15%;" src="{% static 'images/ui/orange_star.png' %}"/>
|
|
<img style="width:15%;" src="{% static 'images/ui/star.png' %}"/>
|
|
<img style="width:15%;" src="{% static 'images/ui/star.png' %}"/>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<div data-cell-index="8" class="oh-sticky-table__td">{{ticket.tags.all|join:" , "}}</div>
|
|
<div class="oh-sticky-table__td oh-sticky-table__right" onclick="event.stopPropagation()">
|
|
<div class="oh-btn-group">
|
|
<a
|
|
href="{% url 'ticket-detail' ticket.id %}"
|
|
type="button" title="{% trans 'View' %}"
|
|
class="oh-btn oh-btn--light-bkg p-3 w-50"
|
|
>
|
|
<ion-icon name="eye-outline"></ion-icon>
|
|
</a>
|
|
<button
|
|
class="oh-btn oh-btn--light-bkg p-3 w-50"
|
|
title="{% trans 'Edit' %}"
|
|
data-toggle="oh-modal-toggle"
|
|
data-target="#objectCreateModal"
|
|
hx-get="{% url 'ticket-update' ticket.id %}"
|
|
hx-target="#objectCreateModalTarget"
|
|
>
|
|
<ion-icon name="create-outline"></ion-icon>
|
|
</button>
|
|
<form
|
|
action="{% url 'ticket-delete' ticket.id %}"
|
|
class="w-50"
|
|
onsubmit="return confirm('{% trans 'Are you sure you want to delete this Ticket?' %}');"
|
|
method='post' onclick="event.stopPropagation()" >
|
|
{% csrf_token %}
|
|
<button
|
|
type="submit"
|
|
class="oh-btn oh-btn--danger-outline oh-btn--light-bkg p-3 w-100"
|
|
title="{% trans 'Delete' %}"
|
|
>
|
|
<ion-icon
|
|
class="me-1 md hydrated"
|
|
name="trash-outline"
|
|
role="img"
|
|
aria-label="trash outline"
|
|
></ion-icon>
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- end of Sticky Table -->
|
|
|
|
<!-- start of pagination -->
|
|
<div class="oh-pagination">
|
|
<span class="oh-pagination__page">
|
|
{% trans "Page" %} {{ my_tickets.number }} {% trans "of" %} {{ my_tickets.paginator.num_pages }}.
|
|
</span>
|
|
<nav class="oh-pagination__nav">
|
|
<div class="oh-pagination__input-container me-3">
|
|
<span class="oh-pagination__label me-1">{% trans "Page" %}</span>
|
|
<input
|
|
type="number"
|
|
name="my_page"
|
|
class="oh-pagination__input"
|
|
value="{{my_tickets.number}}"
|
|
hx-get="{% url 'ticket-filter' %}?{{pd}}"
|
|
hx-target="#view-container"
|
|
min="1"
|
|
/>
|
|
<span class="oh-pagination__label"
|
|
>{% trans "of" %} {{my_tickets.paginator.num_pages}}</span
|
|
>
|
|
</div>
|
|
<ul class="oh-pagination__items">
|
|
{% if my_tickets.has_previous %}
|
|
<li class="oh-pagination__item oh-pagination__item--wide">
|
|
<a
|
|
hx-target="#view-container"
|
|
hx-get="{% url 'ticket-filter' %}?{{pd}}&my_page=1"
|
|
class="oh-pagination__link"
|
|
>{% trans "First" %}</a
|
|
>
|
|
</li>
|
|
<li class="oh-pagination__item oh-pagination__item--wide">
|
|
<a
|
|
hx-target="#view-container"
|
|
hx-get="{% url 'ticket-filter' %}?{{pd}}&my_page={{ my_tickets.previous_page_number }}"
|
|
class="oh-pagination__link"
|
|
>{% trans "Previous" %}</a
|
|
>
|
|
</li>
|
|
{% endif %} {% if my_tickets.has_next %}
|
|
<li class="oh-pagination__item oh-pagination__item--wide">
|
|
<a
|
|
hx-target="#view-container"
|
|
hx-get="{% url 'ticket-filter' %}?{{pd}}&my_page={{ my_tickets.next_page_number }}"
|
|
class="oh-pagination__link"
|
|
>{% trans "Next" %}</a
|
|
>
|
|
</li>
|
|
<li class="oh-pagination__item oh-pagination__item--wide">
|
|
<a
|
|
hx-target="#view-container"
|
|
hx-get="{% url 'ticket-filter' %}?{{pd}}&my_page={{ my_tickets.paginator.num_pages }}"
|
|
class="oh-pagination__link"
|
|
>{% trans "Last" %}</a
|
|
>
|
|
</li>
|
|
{% endif %}
|
|
</ul>
|
|
</nav>
|
|
</div>
|
|
<!-- end of pagination -->
|
|
</div>
|
|
</div>
|
|
{% else %}
|
|
<!-- start of empty page -->
|
|
<div style="display: flex; flex-direction: column; justify-content: center; align-items: center; height: 100%;" >
|
|
<img
|
|
style="width: 150px; height: 150px"
|
|
src="{% static 'images/ui/no-results.png' %}"
|
|
class="oh-404__image mb-4"
|
|
/>
|
|
<h5 class="oh-404__subtitle">
|
|
{% trans "No search result found!" %}
|
|
</h5>
|
|
</div>
|
|
<!-- end of empty page -->
|
|
{% endif %}
|
|
</div>
|
|
<div class="oh-tabs__content" id="tab_2">
|
|
{% if allocated_tickets %}
|
|
<div class="oh-table_sticky--wrapper">
|
|
<div class="oh-sticky-dropdown--header">
|
|
<div class="oh-dropdown" x-data="{open: false}">
|
|
<button class="oh-sticky-dropdown_btn " @click="open = !open"><ion-icon name="ellipsis-vertical-sharp"
|
|
role="img" class="md hydrated" aria-label="ellipsis vertical sharp"></ion-icon></button>
|
|
<div class="oh-dropdown__menu oh-sticky-table_dropdown" x-show="open" @click.outside="open = false">
|
|
<ul class="oh-dropdown__items" id="SuggestedTicketsCells">
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="suggested-ticket-table" data-table-name="suggested_ticket_table">
|
|
<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" style="width: 10px">
|
|
<div class="centered-div">
|
|
<input
|
|
type="checkbox"
|
|
title='{% trans "Select All" %}'
|
|
class="oh-input oh-input__checkbox allocatedTicketsAll"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div class="oh-sticky-table__th">{% trans "Ticket Id" %}</div>
|
|
<div data-cell-index="11" data-cell-title='{% trans "Title" %}'
|
|
class="oh-sticky-table__th {% if request.sort_option.order == '-title' %}arrow-up {% elif request.sort_option.order == 'title' %}arrow-down {% else %}arrow-up-down {% endif %}" hx-target='#view-container' hx-get="{% url 'ticket-filter' %}?{{pd}}&sortby=title"
|
|
>{% trans "Title" %}</div>
|
|
<div data-cell-index="12" data-cell-title='{% trans "Owner" %}'
|
|
class="oh-sticky-table__th {% if request.sort_option.order == '-employee_id' %}arrow-up {% elif request.sort_option.order == 'employee_id' %}arrow-down {% else %}arrow-up-down {% endif %}" hx-target='#view-container' hx-get="{% url 'ticket-filter' %}?{{pd}}&sortby=employee_id"
|
|
>{% trans "Owner" %}</div>
|
|
<div data-cell-index="13" data-cell-title='{% trans "Type" %}'
|
|
class="oh-sticky-table__th {% if request.sort_option.order == '-ticket_type__title' %}arrow-up {% elif request.sort_option.order == 'ticket_type__title' %}arrow-down {% else %}arrow-up-down {% endif %}" hx-target='#view-container' hx-get="{% url 'ticket-filter' %}?{{pd}}&sortby=ticket_type__title"
|
|
>{% trans "Type" %}</div>
|
|
<div data-cell-index="14" data-cell-title='{% trans "Forward to" %}' class="oh-sticky-table__th">{% trans "Forward to" %}</div>
|
|
<div data-cell-index="15" data-cell-title='{% trans "Assigned to" %}' class="oh-sticky-table__th">{% trans "Assigned to" %}</div>
|
|
<div data-cell-index="16" data-cell-title='{% trans "Status" %}' class="oh-sticky-table__th">{% trans "Status" %}</div>
|
|
<div data-cell-index="17" data-cell-title='{% trans "Priority" %}' class="oh-sticky-table__th">{% trans "Priority" %}</div>
|
|
<div data-cell-index="18" data-cell-title='{% trans "Tags" %}' class="oh-sticky-table__th">{% trans "Tags" %}</div>
|
|
<div class="oh-sticky-table__th oh-sticky-table__right" style="width:200px;">{% trans "Actions" %}</div>
|
|
</div>
|
|
</div>
|
|
<div class="oh-sticky-table__tbody">
|
|
{% for ticket in allocated_tickets %}
|
|
<div class="oh-sticky-table__tr" onclick="window.location.href = `{% url 'ticket-detail' ticket.id %}`" >
|
|
<div class="oh-sticky-table__sd {% if ticket.status == 'new' %}row-status--blue
|
|
{% elif ticket.status == 'in_progress' %}row-status--orange
|
|
{% elif ticket.status == 'resolved' %}row-status--yellowgreen
|
|
{% elif ticket.status == 'on_hold' %}row-status--red
|
|
{% elif ticket.status == 'canceled' %}row-status--grey{% endif %}"
|
|
onclick="event.stopPropagation()"
|
|
>
|
|
<div class="centered-div">
|
|
<input
|
|
type="checkbox"
|
|
id="{{ticket.id}}"
|
|
onchange="highlightRow($(this))"
|
|
class="oh-input holiday-checkbox oh-input__checkbox allocated-tickets-row"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div class="oh-sticky-table__td">
|
|
<span class='d-flex justify-content-between align-items-center'
|
|
>
|
|
{{ticket.ticket_type.prefix}}{{ ticket.id|stringformat:"03d" }}
|
|
<span title = 'due {% if ticket.deadline == today %} today {% else %}in {{ticket.deadline|sub:today}}{% endif %}'>
|
|
<ion-icon
|
|
class="text-{% if ticket.deadline < today %}danger {% elif ticket.deadline == today %}warning {% else %}success{% endif %}"
|
|
name="time-sharp"
|
|
>
|
|
</ion-icon>
|
|
</span>
|
|
</span>
|
|
</div>
|
|
<div data-cell-index="11" class="oh-sticky-table__td">{{ticket.title}}</div>
|
|
<div data-cell-index="12" class="oh-sticky-table__td">{{ticket.employee_id}}</div>
|
|
<div data-cell-index="13" class="oh-sticky-table__td">{{ticket.ticket_type}}</div>
|
|
<div data-cell-index="14" class="oh-sticky-table__td">{{ticket.get_raised_on}}</div>
|
|
<div data-cell-index="15" class="oh-sticky-table__td">{{ticket.assigned_to.all|join:" , "}}</div>
|
|
<div data-cell-index="16" class="oh-sticky-table__td">{{ticket.get_status_display}}</div>
|
|
<div data-cell-index="17" class="oh-sticky-table__td">
|
|
{% if ticket.priority == 'high' %}
|
|
<img style="width:15%;" src="{% static 'images/ui/orange_star.png' %}"/>
|
|
<img style="width:15%;" src="{% static 'images/ui/orange_star.png' %}"/>
|
|
<img style="width:15%;" src="{% static 'images/ui/orange_star.png' %}"/>
|
|
{% elif ticket.priority == 'medium' %}
|
|
<img style="width:15%;" src="{% static 'images/ui/orange_star.png' %}"/>
|
|
<img style="width:15%;" src="{% static 'images/ui/orange_star.png' %}"/>
|
|
<img style="width:15%;" src="{% static 'images/ui/star.png' %}"/>
|
|
{% elif ticket.priority == 'low' %}
|
|
<img style="width:15%;" src="{% static 'images/ui/orange_star.png' %}"/>
|
|
<img style="width:15%;" src="{% static 'images/ui/star.png' %}"/>
|
|
<img style="width:15%;" src="{% static 'images/ui/star.png' %}"/>
|
|
{% endif %}
|
|
</div>
|
|
<div data-cell-index="18" class="oh-sticky-table__td">{{ticket.tags.all|join:" , "}}</div>
|
|
<div class="oh-sticky-table__td oh-sticky-table__right" onclick="event.stopPropagation()">
|
|
<div class="oh-btn-group" style="border:none">
|
|
{% if ticket.assigned_to.all or request.user.employee_get == ticket.employee_id %}
|
|
<a
|
|
href="#"
|
|
class="oh-btn oh-btn--info w-100 oh-btn--disabled"
|
|
title="{% trans 'claim' %}"
|
|
>
|
|
{% trans "Claim" %}
|
|
</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>
|
|
{% comment %} {% trans "Claim" %} {% endcomment %}
|
|
</a>
|
|
{% endif %}
|
|
{% if ticket.employee_id == request.user.employee_get or perms.helpdesk.changeticket %}
|
|
<button
|
|
class="oh-btn oh-btn--light-bkg p-3 w-100"
|
|
title="{% trans 'Edit' %}"
|
|
data-toggle="oh-modal-toggle"
|
|
data-target="#objectCreateModal"
|
|
hx-get="{% url 'ticket-update' ticket.id %}"
|
|
hx-target="#objectCreateModalTarget"
|
|
>
|
|
<ion-icon name="create-outline"></ion-icon>
|
|
</button>
|
|
{% endif %}
|
|
{% if ticket.employee_id == request.user.employee_get or perms.helpdesk.deleteticket %}
|
|
<form
|
|
action="{% url 'ticket-delete' ticket.id %}"
|
|
onsubmit="return confirm('{% trans 'Are you sure you want to delete this Ticket?' %}');"
|
|
method='post' onclick="event.stopPropagation()"
|
|
style="width:100%"
|
|
>
|
|
{% csrf_token %}
|
|
<button
|
|
type="submit"
|
|
class="oh-btn oh-btn--danger-outline oh-btn--light-bkg p-3 w-100"
|
|
title="{% trans 'Delete' %}"
|
|
>
|
|
<ion-icon
|
|
class="me-1 md hydrated"
|
|
name="trash-outline"
|
|
role="img"
|
|
aria-label="trash outline"
|
|
></ion-icon>
|
|
</button>
|
|
</form>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="oh-pagination">
|
|
<span class="oh-pagination__page">
|
|
{% trans "Page" %} {{ allocated_tickets.number }} {% trans "of" %} {{ allocated_tickets.paginator.num_pages }}.
|
|
</span>
|
|
<nav class="oh-pagination__nav">
|
|
<div class="oh-pagination__input-container me-3">
|
|
<span class="oh-pagination__label me-1">{% trans "Page" %}</span>
|
|
<input
|
|
type="number"
|
|
name="allocated_page"
|
|
class="oh-pagination__input"
|
|
value="{{allocated_tickets.number}}"
|
|
hx-get="{% url 'ticket-filter' %}?{{pd}}"
|
|
hx-target="#view-container"
|
|
min="1"
|
|
/>
|
|
<span class="oh-pagination__label"
|
|
>{% trans "of" %} {{allocated_tickets.paginator.num_pages}}</span
|
|
>
|
|
</div>
|
|
<ul class="oh-pagination__items">
|
|
{% if allocated_tickets.has_previous %}
|
|
<li class="oh-pagination__item oh-pagination__item--wide">
|
|
<a
|
|
hx-target="#view-container"
|
|
hx-get="{% url 'ticket-filter' %}?{{pd}}&allocated_page=1"
|
|
class="oh-pagination__link"
|
|
>{% trans "First" %}</a
|
|
>
|
|
</li>
|
|
<li class="oh-pagination__item oh-pagination__item--wide">
|
|
<a
|
|
hx-target="#view-container"
|
|
hx-get="{% url 'ticket-filter' %}?{{pd}}&allocated_page={{ allocated_tickets.previous_page_number }}"
|
|
class="oh-pagination__link"
|
|
>{% trans "Previous" %}</a
|
|
>
|
|
</li>
|
|
{% endif %} {% if allocated_tickets.has_next %}
|
|
<li class="oh-pagination__item oh-pagination__item--wide">
|
|
<a
|
|
hx-target="#view-container"
|
|
hx-get="{% url 'ticket-filter' %}?{{pd}}&allocated_page={{ allocated_tickets.next_page_number }}"
|
|
class="oh-pagination__link"
|
|
>{% trans "Next" %}</a
|
|
>
|
|
</li>
|
|
<li class="oh-pagination__item oh-pagination__item--wide">
|
|
<a
|
|
hx-target="#view-container"
|
|
hx-get="{% url 'ticket-filter' %}?{{pd}}&allocated_page={{ allocated_tickets.paginator.num_pages }}"
|
|
class="oh-pagination__link"
|
|
>{% trans "Last" %}</a
|
|
>
|
|
</li>
|
|
{% endif %}
|
|
</ul>
|
|
</nav>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% else %}
|
|
<!-- start of empty page -->
|
|
<div style="display: flex; flex-direction: column; justify-content: center; align-items: center; height: 100%;" >
|
|
<img
|
|
style="width: 150px; height: 150px"
|
|
src="{% static 'images/ui/no-results.png' %}"
|
|
class="oh-404__image mb-4"
|
|
/>
|
|
<h5 class="oh-404__subtitle">
|
|
{% trans "No search result found!" %}
|
|
</h5>
|
|
</div>
|
|
<!-- end of empty page -->
|
|
{% endif %}
|
|
</div>
|
|
<div class="oh-tabs__content" id="tab_3">
|
|
{% if all_tickets %}
|
|
<div class="oh-table_sticky--wrapper">
|
|
<div class="oh-sticky-dropdown--header">
|
|
<div class="oh-dropdown" x-data="{open: false}">
|
|
<button class="oh-sticky-dropdown_btn " @click="open = !open"><ion-icon name="ellipsis-vertical-sharp"
|
|
role="img" class="md hydrated" aria-label="ellipsis vertical sharp"></ion-icon></button>
|
|
<div class="oh-dropdown__menu oh-sticky-table_dropdown" x-show="open" @click.outside="open = false">
|
|
<ul class="oh-dropdown__items" id="AllTicketsCells">
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="all-ticket-table" data-table-name="all_ticket_table">
|
|
<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" style="width: 10px">
|
|
<div class="centered-div">
|
|
<input
|
|
type="checkbox"
|
|
title='{% trans "Select All" %}'
|
|
class="oh-input oh-input__checkbox allTicketsAll"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div class="oh-sticky-table__th">{% trans "Ticket Id" %}</div>
|
|
<div data-cell-index="21" data-cell-title='{% trans "Title" %}'
|
|
class="oh-sticky-table__th {% if request.sort_option.order == '-title' %}arrow-up {% elif request.sort_option.order == 'title' %}arrow-down {% else %}arrow-up-down {% endif %}" hx-target='#view-container' hx-get="{% url 'ticket-filter' %}?{{pd}}&sortby=title"
|
|
>{% trans "Title" %}</div>
|
|
<div data-cell-index="22" data-cell-title='{% trans "Owner" %}'
|
|
class="oh-sticky-table__th {% if request.sort_option.order == '-employee_id' %}arrow-up {% elif request.sort_option.order == 'employee_id' %}arrow-down {% else %}arrow-up-down {% endif %}" hx-target='#view-container' hx-get="{% url 'ticket-filter' %}?{{pd}}&sortby=employee_id"
|
|
>{% trans "Owner" %}</div>
|
|
<div data-cell-index="23" data-cell-title='{% trans "Type" %}'
|
|
class="oh-sticky-table__th {% if request.sort_option.order == '-ticket_type__title' %}arrow-up {% elif request.sort_option.order == 'ticket_type__title' %}arrow-down {% else %}arrow-up-down {% endif %}" hx-target='#view-container' hx-get="{% url 'ticket-filter' %}?{{pd}}&sortby=ticket_type__title"
|
|
>{% trans "Type" %}</div>
|
|
<div data-cell-index="24" data-cell-title='{% trans "Forward to" %}' class="oh-sticky-table__th">{% trans "Forward to" %}</div>
|
|
<div data-cell-index="25" data-cell-title='{% trans "Assigned to" %}' class="oh-sticky-table__th">{% trans "Assigned to" %}</div>
|
|
<div data-cell-index="26" data-cell-title='{% trans "Status" %}' class="oh-sticky-table__th">{% trans "Status" %}</div>
|
|
<div data-cell-index="27" data-cell-title='{% trans "Priority" %}' class="oh-sticky-table__th">{% trans "Priority" %}</div>
|
|
<div data-cell-index="28" data-cell-title='{% trans "Tags" %}' class="oh-sticky-table__th">{% trans "Tags" %}</div>
|
|
<div class="oh-sticky-table__th oh-sticky-table__right">{% trans "Actions" %}</div>
|
|
</div>
|
|
</div>
|
|
<div class="oh-sticky-table__tbody">
|
|
{% for ticket in all_tickets %}
|
|
<div class="oh-sticky-table__tr" onclick="window.location.href = `{% url 'ticket-detail' ticket.id %}`">
|
|
<div class="oh-sticky-table__sd {% if ticket.status == 'new' %}row-status--blue
|
|
{% elif ticket.status == 'in_progress' %}row-status--orange
|
|
{% elif ticket.status == 'resolved' %}row-status--yellowgreen
|
|
{% elif ticket.status == 'on_hold' %}row-status--red
|
|
{% elif ticket.status == 'canceled' %}row-status--grey{% endif %}"
|
|
onclick="event.stopPropagation()"
|
|
>
|
|
<div class="centered-div">
|
|
<input
|
|
type="checkbox"
|
|
id="{{ticket.id}}"
|
|
onchange="highlightRow($(this))"
|
|
class="oh-input holiday-checkbox oh-input__checkbox all-tickets-row"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div class="oh-sticky-table__td">
|
|
<span class='d-flex justify-content-between align-items-center'
|
|
>
|
|
{{ticket.ticket_type.prefix}}{{ ticket.id|stringformat:"03d" }}
|
|
<span title = 'due {% if ticket.deadline == today %} today {% else %}in {{ticket.deadline|sub:today}}{% endif %}'>
|
|
<ion-icon
|
|
class="text-{% if ticket.deadline < today %}danger {% elif ticket.deadline == today %}warning {% else %}success{% endif %}"
|
|
name="time-sharp"
|
|
>
|
|
</ion-icon>
|
|
</span>
|
|
</span>
|
|
</div>
|
|
<div data-cell-index="21" class="oh-sticky-table__td">{{ticket.title}}</div>
|
|
<div data-cell-index="22" class="oh-sticky-table__td">{{ticket.employee_id}}</div>
|
|
<div data-cell-index="23" class="oh-sticky-table__td">{{ticket.ticket_type}}</div>
|
|
<div data-cell-index="24" class="oh-sticky-table__td">{{ticket.get_raised_on}}</div>
|
|
<div data-cell-index="25" class="oh-sticky-table__td">{{ticket.assigned_to.all|join:" , "}}</div>
|
|
<div data-cell-index="26" class="oh-sticky-table__td">{{ticket.get_status_display}}</div>
|
|
<div data-cell-index="27" class="oh-sticky-table__td">
|
|
{% if ticket.priority == 'high' %}
|
|
<img style="width:15%;" src="{% static 'images/ui/orange_star.png' %}"/>
|
|
<img style="width:15%;" src="{% static 'images/ui/orange_star.png' %}"/>
|
|
<img style="width:15%;" src="{% static 'images/ui/orange_star.png' %}"/>
|
|
{% elif ticket.priority == 'medium' %}
|
|
<img style="width:15%;" src="{% static 'images/ui/orange_star.png' %}"/>
|
|
<img style="width:15%;" src="{% static 'images/ui/orange_star.png' %}"/>
|
|
<img style="width:15%;" src="{% static 'images/ui/star.png' %}"/>
|
|
{% elif ticket.priority == 'low' %}
|
|
<img style="width:15%;" src="{% static 'images/ui/orange_star.png' %}"/>
|
|
<img style="width:15%;" src="{% static 'images/ui/star.png' %}"/>
|
|
<img style="width:15%;" src="{% static 'images/ui/star.png' %}"/>
|
|
{% endif %}
|
|
</div>
|
|
<div data-cell-index="28" class="oh-sticky-table__td">{{ticket.tags.all|join:" , "}}</div>
|
|
<div class="oh-sticky-table__td oh-sticky-table__right" onclick="event.stopPropagation()">
|
|
<div class="oh-btn-group">
|
|
<a
|
|
href="{% url 'ticket-detail' ticket.id %}"
|
|
type="button" title="{% trans 'View' %}"
|
|
class="oh-btn oh-btn--light-bkg p-3 w-50"
|
|
>
|
|
<ion-icon name="eye-outline"></ion-icon>
|
|
</a>
|
|
<button
|
|
class="oh-btn oh-btn--light-bkg p-3 w-50"
|
|
title="{% trans 'Edit' %}"
|
|
data-toggle="oh-modal-toggle"
|
|
data-target="#objectCreateModal"
|
|
hx-get="{% url 'ticket-update' ticket.id %}"
|
|
hx-target="#objectCreateModalTarget"
|
|
>
|
|
<ion-icon name="create-outline"></ion-icon>
|
|
</button>
|
|
<form
|
|
action="{% url 'ticket-delete' ticket.id %}"
|
|
class="w-50"
|
|
onsubmit="return confirm('{% trans 'Are you sure you want to delete this Ticket?' %}');"
|
|
method='post' onclick="event.stopPropagation()" >
|
|
{% csrf_token %}
|
|
<button
|
|
type="submit"
|
|
class="oh-btn oh-btn--danger-outline oh-btn--light-bkg p-3 w-100"
|
|
title="{% trans 'Delete' %}"
|
|
>
|
|
<ion-icon
|
|
class="me-1 md hydrated"
|
|
name="trash-outline"
|
|
role="img"
|
|
aria-label="trash outline"
|
|
></ion-icon>
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="oh-pagination">
|
|
<span class="oh-pagination__page">
|
|
{% trans "Page" %} {{ all_tickets.number }} {% trans "of" %} {{ all_tickets.paginator.num_pages }}.
|
|
</span>
|
|
<nav class="oh-pagination__nav">
|
|
<div class="oh-pagination__input-container me-3">
|
|
<span class="oh-pagination__label me-1">{% trans "Page" %}</span>
|
|
<input
|
|
type="number"
|
|
name="all_page"
|
|
class="oh-pagination__input"
|
|
value="{{all_tickets.number}}"
|
|
hx-get="{% url 'ticket-filter' %}?{{pd}}"
|
|
hx-target="#view-container"
|
|
min="1"
|
|
/>
|
|
<span class="oh-pagination__label"
|
|
>{% trans "of" %} {{all_tickets.paginator.num_pages}}</span
|
|
>
|
|
</div>
|
|
<ul class="oh-pagination__items">
|
|
{% if all_tickets.has_previous %}
|
|
<li class="oh-pagination__item oh-pagination__item--wide">
|
|
<a
|
|
hx-target="#view-container"
|
|
hx-get="{% url 'ticket-filter' %}?{{pd}}&all_page=1"
|
|
class="oh-pagination__link"
|
|
>{% trans "First" %}</a
|
|
>
|
|
</li>
|
|
<li class="oh-pagination__item oh-pagination__item--wide">
|
|
<a
|
|
hx-target="#view-container"
|
|
hx-get="{% url 'ticket-filter' %}?{{pd}}&all_page={{ all_tickets.previous_page_number }}"
|
|
class="oh-pagination__link"
|
|
>{% trans "Previous" %}</a
|
|
>
|
|
</li>
|
|
{% endif %} {% if all_tickets.has_next %}
|
|
<li class="oh-pagination__item oh-pagination__item--wide">
|
|
<a
|
|
hx-target="#view-container"
|
|
hx-get="{% url 'ticket-filter' %}?{{pd}}&all_page={{ all_tickets.next_page_number }}"
|
|
class="oh-pagination__link"
|
|
>{% trans "Next" %}</a
|
|
>
|
|
</li>
|
|
<li class="oh-pagination__item oh-pagination__item--wide">
|
|
<a
|
|
hx-target="#view-container"
|
|
hx-get="{% url 'ticket-filter' %}?{{pd}}&all_page={{ all_tickets.paginator.num_pages }}"
|
|
class="oh-pagination__link"
|
|
>{% trans "Last" %}</a
|
|
>
|
|
</li>
|
|
{% endif %}
|
|
</ul>
|
|
</nav>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% else %}
|
|
<!-- start of empty page -->
|
|
<div style="display: flex; flex-direction: column; justify-content: center; align-items: center; height: 100%;" >
|
|
<img
|
|
style="width: 150px; height: 150px"
|
|
src="{% static 'images/ui/no-results.png' %}"
|
|
class="oh-404__image mb-4"
|
|
/>
|
|
<h5 class="oh-404__subtitle">
|
|
{% trans "No search result found!" %}
|
|
</h5>
|
|
</div>
|
|
<!-- end of empty page -->
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
// TO recogonise recently used tab
|
|
var activeTab = localStorage.getItem("activeTabTicket");
|
|
if (activeTab != null) {
|
|
var tab = $(`[data-target="${activeTab}"]`);
|
|
var tabContent = $(activeTab);
|
|
$(tab).attr("class", "oh-tabs__tab oh-tabs__tab--active");
|
|
$(tabContent).attr(
|
|
"class",
|
|
"oh-tabs__content oh-tabs__content--active"
|
|
);
|
|
} else {
|
|
$('[data-target="#tab_1"]').attr(
|
|
"class",
|
|
"oh-tabs__tab oh-tabs__tab--active"
|
|
);
|
|
$("#tab_1").attr("class", "oh-tabs__content oh-tabs__content--active");
|
|
}
|
|
$(".oh-tabs__tab").click(function (e) {
|
|
var activeTab = $(this).attr("data-target");
|
|
localStorage.setItem("activeTabTicket", activeTab);
|
|
});
|
|
|
|
// TO toggle class for select all button in All tickets tab
|
|
$(".allTicketsAll").change(function (e) {
|
|
var is_checked = $(this).is(":checked");
|
|
if (is_checked) {
|
|
$(".all-tickets-row").prop("checked", true)
|
|
.closest(".oh-sticky-table__tr")
|
|
.addClass("highlight-selected");
|
|
} else {
|
|
$(".all-tickets-row").prop("checked", false)
|
|
.closest(".oh-sticky-table__tr")
|
|
.removeClass("highlight-selected");
|
|
}
|
|
});
|
|
|
|
// TO toggle class for select all button in Allocated tickets tab
|
|
$(".allocatedTicketsAll").change(function (e) {
|
|
var is_checked = $(this).is(":checked");
|
|
if (is_checked) {
|
|
$(".allocated-tickets-row").prop("checked", true)
|
|
.closest(".oh-sticky-table__tr")
|
|
.addClass("highlight-selected");
|
|
} else {
|
|
$(".allocated-tickets-row").prop("checked", false)
|
|
.closest(".oh-sticky-table__tr")
|
|
.removeClass("highlight-selected");
|
|
}
|
|
});
|
|
|
|
// TO toggle class for select all button in My tickets tab
|
|
$(".myTicketsAll").change(function (e) {
|
|
var is_checked = $(this).is(":checked");
|
|
if (is_checked) {
|
|
$(".my-tickets-row").prop("checked", true)
|
|
.closest(".oh-sticky-table__tr")
|
|
.addClass("highlight-selected");
|
|
} else {
|
|
$(".my-tickets-row").prop("checked", false)
|
|
.closest(".oh-sticky-table__tr")
|
|
.removeClass("highlight-selected");
|
|
}
|
|
});
|
|
$(document).ready(function () {
|
|
tickTicketsCheckboxes();
|
|
$(".my-tickets-row").change(function () {
|
|
if ($('.myTicketsAll').is(":checked")) {
|
|
$('.myTicketsAll').prop("checked", false);
|
|
}
|
|
addingTicketsIds();
|
|
});
|
|
$(".myTicketsAll").change(function () {
|
|
addingTicketsIds();
|
|
});
|
|
|
|
$(".allocated-tickets-row").change(function () {
|
|
if ($('.allocatedTicketsAll').is(":checked")) {
|
|
$('.allocatedTicketsAll').prop("checked", false);
|
|
}
|
|
addingTicketsIds();
|
|
});
|
|
$(".allocatedTicketsAll").change(function () {
|
|
addingTicketsIds();
|
|
});
|
|
$(".all-tickets-row").change(function () {
|
|
if ($('.allTicketsAll').is(":checked")) {
|
|
$('.allTicketsAll').prop("checked", false);
|
|
}
|
|
addingTicketsIds();
|
|
});
|
|
$(".allTicketsAll").change(function () {
|
|
addingTicketsIds();
|
|
});
|
|
|
|
$("#selectAllTickets").click(function () {
|
|
selectAllTickets();
|
|
});
|
|
$("#unselectAllTickets").click(function () {
|
|
unselectAllTickets();
|
|
});
|
|
{% comment %} $("#exportObjectives").click(function (e) {
|
|
exportObjectives();
|
|
}); {% endcomment %}
|
|
});
|
|
// start of column toggle //
|
|
//my tickets//
|
|
toggleColumns("my-ticket-table","MyTicketsCells")
|
|
localStorageMyTicketsCells = localStorage.getItem("my_ticket_table")
|
|
if (!localStorageMyTicketsCells) {
|
|
$("#MyTicketsCells").find("[type=checkbox]").prop("checked",true)
|
|
}
|
|
|
|
//suggested tickets//
|
|
toggleColumns("suggested-ticket-table","SuggestedTicketsCells")
|
|
localStorageSuggestedTicketsCells = localStorage.getItem("suggested_ticket_table")
|
|
if (!localStorageSuggestedTicketsCells) {
|
|
$("#SuggestedTicketsCells").find("[type=checkbox]").prop("checked",true)
|
|
}
|
|
|
|
//all tickets//
|
|
toggleColumns("all-ticket-table","AllTicketsCells")
|
|
localStorageAllTicketsCells = localStorage.getItem("all_ticket_table")
|
|
if (!localStorageAllTicketsCells) {
|
|
$("#AllTicketsCells").find("[type=checkbox]").prop("checked",true)
|
|
}
|
|
$("[type=checkbox]").change()
|
|
// end of toggle columns //
|
|
</script>
|
|
<script src="{% static 'tickets/action.js' %}"></script> |