492 lines
26 KiB
HTML
492 lines
26 KiB
HTML
{% extends "layouts/base.html" %}
|
|
{% load static %}
|
|
|
|
{% block title %} Tickets {% endblock title %}
|
|
|
|
<!-- Specific CSS goes HERE -->
|
|
{% block stylesheets %}
|
|
<link rel="stylesheet" href="{% static '/css/select2-bootstrap.min.css' %}">
|
|
{% endblock stylesheets %}
|
|
|
|
{% block content %}
|
|
|
|
<!-- ### $App Screen Content ### -->
|
|
<main class='main-content'>
|
|
<div id='mainContent'>
|
|
<div class="full-container" style="overflow: hidden;">
|
|
<div class="email-app">
|
|
<div class="email-side-nav remain-height ov-h">
|
|
<div class="h-100 layers">
|
|
<div class="p-20 bg-body-tertiary layer w-100">
|
|
<button type="button" class="btn btn-danger c-white w-100" data-bs-toggle="modal" data-bs-target="#ticketModal">New Ticket</button>
|
|
</div>
|
|
<div class="scrollable pos-r ov-h bdT layer w-100 fxg-1 bg-body">
|
|
<ul id="filterSidebar" class="p-20 nav flex-column">
|
|
|
|
{% if priorities %}
|
|
|
|
<li class="nav-item mT-10">
|
|
<h6 class="mx-3">Priorities</h6>
|
|
</li>
|
|
|
|
<li id="filterPriorityAll" class="nav-item filter-priority">
|
|
<label for="filterPriority-all" class="nav-link text-reset actived">
|
|
<div class="peers ai-c jc-sb">
|
|
<div class="peer peer-greed">
|
|
<input type="radio" id="filterPriority-all" name="filterPriorities" class="form-check-input me-2" checked="checked" value="all">
|
|
<span>All</span>
|
|
</div>
|
|
<!-- <div class="peer">
|
|
<span class="badge rounded-pill bgc-green-50 c-green-700">0</span>
|
|
</div> -->
|
|
</div>
|
|
</label>
|
|
</li>
|
|
|
|
{% for priority in priorities %}
|
|
|
|
<li class="nav-item filter-priority">
|
|
<label for="filterPriority-{{ priority.uuid }}" class="nav-link text-reset actived">
|
|
<div class="peers ai-c jc-sb">
|
|
<div class="peer peer-greed">
|
|
<input type="radio" id="filterPriority-{{ priority.uuid }}" name="filterPriorities" class="form-check-input me-2" value="{{ priority.uuid }}">
|
|
<span>{{ priority.title }}</span>
|
|
</div>
|
|
<div class="peer">
|
|
<span class="badge rounded-pill" style="color: {{ priority.colour }}; background-color: {{ priority.backgroundcolour }};">0</span>
|
|
</div>
|
|
</div>
|
|
</label>
|
|
</li>
|
|
|
|
{% endfor %}
|
|
|
|
{% endif %}
|
|
|
|
<li class="nav-item">
|
|
<hr class="mY-30 border-secondary">
|
|
</li>
|
|
|
|
{% if tags %}
|
|
|
|
<li class="nav-item">
|
|
<h6 class="peers ai-c jc-sb mb-2 px-3">
|
|
<span class="peer-greed">Tags</span>
|
|
<div class="dropdown">
|
|
<button type="button" class="peer text-body bg-none border-none" data-bs-toggle="dropdown">
|
|
<i class="ti-more-alt"></i>
|
|
</button>
|
|
<ul class="dropdown-menu">
|
|
<li>
|
|
<span class="dropdown-item-text">Tag Filtering</span>
|
|
</li>
|
|
<li>
|
|
<label for="ticketTags-AND" class="dropdown-item">
|
|
<div class="form-check form-check-switch">
|
|
<span class="form-check-label">Strict</span>
|
|
<input type="radio" name="ticketTags" id="ticketTags-AND" class="form-check-input" checked="checked" value="AND">
|
|
</div>
|
|
</label>
|
|
</li>
|
|
<li>
|
|
<label for="ticketTags-OR" class="dropdown-item">
|
|
<div class="form-check form-check-switch">
|
|
<span class="form-check-label">Loose</span>
|
|
<input type="radio" name="ticketTags" id="ticketTags-OR" class="form-check-input" value="OR">
|
|
</div>
|
|
</label>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</h6>
|
|
</li>
|
|
|
|
{% for tag in tags %}
|
|
|
|
<li class="nav-item filter-tags">
|
|
<label for="filterTag-{{ tag.uuid }}" class="nav-link text-reset actived">
|
|
<div class="peers ai-c jc-sb">
|
|
<div class="peer peer-greed">
|
|
<input type="checkbox" id="filterTag-{{ tag.uuid }}" class="form-check-input me-2" value="{{ tag.uuid }}">
|
|
<span>{{ tag.title }}</span>
|
|
</div>
|
|
<div class="peer">
|
|
<span class="badge rounded-pill" style="color: {{ tag.colour }}; background-color: {{ tag.backgroundcolour }};">0</span>
|
|
</div>
|
|
</div>
|
|
</label>
|
|
</li>
|
|
|
|
{% endfor %}
|
|
|
|
{% endif %}
|
|
|
|
<li class="nav-item">
|
|
<hr class="mY-30 border-secondary">
|
|
</li>
|
|
|
|
{% if departments %}
|
|
|
|
<li class="nav-item">
|
|
<h6 class="px-3">Departments</h6>
|
|
</li>
|
|
|
|
<li id="filterDepartmentAll" class="nav-item filter-department">
|
|
<label for="filterDepartment-all" class="nav-link text-reset actived">
|
|
<div class="peers ai-c jc-sb">
|
|
<div class="peer peer-greed">
|
|
<input type="radio" id="filterDepartment-all" name="filterDepartment" class="form-check-input me-2" checked="checked" value="all">
|
|
<span>All</span>
|
|
</div>
|
|
<!-- <div class="peer">
|
|
<span class="badge rounded-pill bgc-green-50 c-green-700">0</span>
|
|
</div> -->
|
|
</div>
|
|
</label>
|
|
</li>
|
|
|
|
{% for department in departments %}
|
|
|
|
<li class="nav-item filter-department">
|
|
<label for="filterDepartment-{{ department.uuid }}" class="nav-link text-reset actived">
|
|
<div class="peers ai-c jc-sb">
|
|
<div class="peer peer-greed">
|
|
<input type="radio" id="filterDepartment-{{ department.uuid }}" name="filterDepartment" class="form-check-input me-2" value="{{ department.uuid }}">
|
|
<span>{{ department.title }}</span>
|
|
</div>
|
|
<div class="peer">
|
|
<span class="badge rounded-pill bg-secondary-subtle text-secondary-emphasis">0</span> <!-- bgc-green-50 c-green-700 -->
|
|
</div>
|
|
</div>
|
|
</label>
|
|
</li>
|
|
|
|
{% endfor %}
|
|
|
|
{% endif %}
|
|
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="email-wrapper row remain-height bg-body">
|
|
<div class="email-list h-100 layers">
|
|
<div class="layer w-100">
|
|
<div class="bg-body-tertiary peers ai-c p-20 fxw-nw">
|
|
<div class="peer me-auto">
|
|
<div class="btn-group" role="group">
|
|
<button type="button" class="email-side-toggle d-n@md+ btn bg-body bdrs-2 mR-3">
|
|
<i class="ti-menu"></i>
|
|
</button>
|
|
<!-- <button type="button" class="btn bgc-white bdrs-2 mR-3 cur-p">
|
|
<i class="ti-tag"></i>
|
|
</button> -->
|
|
<button type="button" class="btn bg-body bdrs-2 mR-3" onclick="javascript:loadTicketItems();">
|
|
<i class="fa fa-refresh"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="peer">
|
|
<div class="btn-group bg-body mX-3" role="group">
|
|
<button type="button" id="ticketItemsPrevPage" class="btn bg-body bdrs-2" onclick="javascript: changeItemsPage(false);" disabled>
|
|
<i class="ti-angle-left"></i>
|
|
</button>
|
|
<div id="paginationCounts" class="bg-body pX-3 small d-flex ai-c">
|
|
<span class="current">-</span>/<span class="total">-</span>
|
|
</div>
|
|
<button type="button" id="ticketItemsNextPage" class="btn bg-body bdrs-2" onclick="javascript: changeItemsPage(true);" disabled>
|
|
<i class="ti-angle-right align-center"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="layer w-100">
|
|
<div class="bdT bdB peers d-flex flex-nowrap">
|
|
<label for="searchTickets" class="peer my-auto mX-15">
|
|
<i class="ti-search"></i>
|
|
</label>
|
|
<input type="text" id="searchTickets" class="form-control m-0 bdw-0 pY-15 pR-20 pL-0 bdrs-0 peer-greed shadow-none" placeholder="Search...">
|
|
<label for="searchTickets" id="ticketCounts" class="peer my-auto mX-15 small">
|
|
<span class="current"></span>/<span class="total"></span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="ticketsContainer" class="layer w-100 fxg-1 scrollable pos-r ov-h">
|
|
<div class="content"></div>
|
|
<div class="none-found pos-a top-50 start-50 translate-middle" style="display: none;">
|
|
<h6 class="fw-bold">No Tickets Found</h6>
|
|
<ul class="text-body-tertiary small">
|
|
<li>Try clearing your search</li>
|
|
<li>Try removing your filters</li>
|
|
<li>Try using the refresh button</li>
|
|
</ul>
|
|
</div>
|
|
<div class="loading bg-body-secondary h-100" style="display: none;">
|
|
{% for i in "x"|rjust:"3" %}
|
|
<div class="email-list-item peers fxw-nw p-20 bdB placeholder-glow" >
|
|
<div class="peer mR-10">
|
|
<span class="placeholder w-2r h-2r bdrs-50p me-2"></span>
|
|
</div>
|
|
<div class="peer peer-greed ov-h">
|
|
<div class="peers ai-c">
|
|
<div class="peer peer-greed">
|
|
<span class="placeholder col-5 rounded"></span>
|
|
</div>
|
|
<div class="peer peer-greed d-flex jc-fe">
|
|
<span class="placeholder col-4 rounded"></span>
|
|
</div>
|
|
</div>
|
|
<span class="placeholder rounded col-7 mT-10"></span>
|
|
<div class="row">
|
|
<span class="col-1"></span>
|
|
<span class="placeholder rounded col-7 mT-10"></span>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
<div class="email-list-item peers fxw-nw p-20 bdB placeholder-glow" >
|
|
<div class="peer mR-10">
|
|
<span class="placeholder w-2r h-2r bdrs-50p me-2"></span>
|
|
</div>
|
|
<div class="peer peer-greed ov-h">
|
|
<div class="peers ai-c">
|
|
<div class="peer peer-greed">
|
|
<span class="placeholder col-6 rounded"></span>
|
|
</div>
|
|
<div class="peer peer-greed d-flex jc-fe">
|
|
<span class="placeholder col-4 rounded"></span>
|
|
</div>
|
|
</div>
|
|
<span class="placeholder rounded col-8 mT-10"></span>
|
|
<span class="placeholder rounded col-7 mT-10"></span>
|
|
</div>
|
|
</div>
|
|
<div class="email-list-item peers fxw-nw p-20 bdB placeholder-glow" >
|
|
<div class="peer mR-10">
|
|
<span class="placeholder w-2r h-2r bdrs-50p me-2"></span>
|
|
</div>
|
|
<div class="peer peer-greed ov-h">
|
|
<div class="peers ai-c">
|
|
<div class="peer peer-greed">
|
|
<span class="placeholder col-5 rounded"></span>
|
|
</div>
|
|
<div class="peer peer-greed d-flex jc-fe">
|
|
<span class="placeholder col-4 rounded"></span>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<span class="col-1"></span>
|
|
<span class="placeholder rounded col-7 mT-10"></span>
|
|
</div>
|
|
<span class="placeholder rounded col-7 mT-10"></span>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
<div class="email-content h-100 bg-body">
|
|
<div class="h-100 scrollable pos-r">
|
|
<div class="bg-body-tertiary peers ai-c jc-sb p-20 fxw-nw d-n@md+">
|
|
<div class="peer">
|
|
<div class="btn-group" role="group">
|
|
<button type="button" class="back-to-mailbox btn bg-body bdrs-2 mR-3">
|
|
<i class="ti-angle-left"></i>
|
|
</button>
|
|
<button type="button" class="btn bg-body bdrs-2 mR-3" onclick="javascript:reloadCurrentTicket();">
|
|
<i class="fa fa-refresh"></i>
|
|
</button>
|
|
<button type="button" class="btn bg-body bdrs-2 mR-3">
|
|
<i class="ti-more-alt"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="peer">
|
|
<div class="btn-group" role="group">
|
|
<button type="button" class="btn bg-body bdrs-2 mR-3" onclick="javascript:changeTicket(false);">
|
|
<i class="ti-angle-left"></i>
|
|
</button>
|
|
<button type="button" class="btn bg-body bdrs-2 mR-3" onclick="javascript:changeTicket(true);">
|
|
<i class="ti-angle-right"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="ticketContent" class="email-content-wrapper">
|
|
<div class="content"></div>
|
|
<div class="loading" style="display: none;">
|
|
|
|
<!-- Header -->
|
|
<div class="ticket-content placeholder-glow">
|
|
<div class="peers ai-c jc-sb pX-40 pY-30">
|
|
<div class="peers peer-greed">
|
|
<div class="peer mR-20">
|
|
<span class="ticket-content-icon placeholder me-2"></span>
|
|
</div>
|
|
<div class="peer-greed">
|
|
<div >
|
|
<span class="placeholder rounded col-4"></span>
|
|
</div>
|
|
<div class="mY-5">
|
|
<span class="placeholder rounded col-5"></span>
|
|
</div>
|
|
<div class="row g-0 ">
|
|
{% for i in "x"|rjust:"12" %}
|
|
<div class="col pe-3">
|
|
<div class="placeholder rounded w-100"></div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Content -->
|
|
<div class="bdT pX-40 pY-30">
|
|
<span class="placeholder rounded col-6 mB-30"></span>
|
|
<div class="row g-3">
|
|
<div class="placeholder rounded col-12 px-3"></div>
|
|
<div class="placeholder rounded col-7"></div>
|
|
<div class="col-1"></div>
|
|
<div class="placeholder rounded col-4"></div>
|
|
<div class="placeholder rounded col-3"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
|
|
<div id="ticketModal" class="modal fade" aria-hidden="true">
|
|
<div class="modal-dialog">
|
|
<form method="post">
|
|
|
|
{% csrf_token %}
|
|
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h3 class="modal-title fs-5">New Ticket</h3>
|
|
<button type="button" class="btn-close" data-bs-toggle="modal"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="mb-3">
|
|
<label for="newTitle" class="form-label">Subject</label>
|
|
<input type="text" name="newTitle" id="newTitle" class="form-control" placeholder="Subject">
|
|
<small class="text-muted">Briefly describe the subject of the ticket.</small>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label for="newDesc" class="form-label">Description</label>
|
|
<div id="newDesc" class="form-control"></div>
|
|
<small class="text-muted">Describe your issue in detail here.</small>
|
|
<!-- class="form-control" -->
|
|
</div>
|
|
<div class="mb-3">
|
|
<label for="newPriority" class="form-label">Priority</label>
|
|
<select name="newPriority" id="newPriority" class="select-2">
|
|
{% for priority in priorities %}
|
|
<option value="{{ priority.uuid }}">{{ priority.title }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
<small class="text-muted">How important is this ticket?</small>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label for="newTags" class="form-label">Tags</label>
|
|
<select name="newTags" id="newTags" class="select-2" multiple="multiple">
|
|
{% for tag in tags %}
|
|
<option value="{{ tag.uuid }}">{{ tag.title }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
<small class="text-muted">Use tags to categorize this ticket.</small>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
|
<button type="submit" class="btn btn-danger c-white">Submit</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
{% endblock content %}
|
|
|
|
{% block javascripts %}
|
|
<!-- Ticket Item Template -->
|
|
<script id="ticketItemTemplate" type="text/template">
|
|
<div class="ticket-item peers fxw-nw p-20 bdB" data-uuid="-1">
|
|
<div class="peer mR-10">
|
|
<img src="" alt="" class="ticket-item-icon me-2">
|
|
</div>
|
|
<div class="peer peer-greed ov-h">
|
|
<div class="peers ai-c mb-2">
|
|
<div class="peer peer-greed">
|
|
<h6 class="ticket-item-author"></h6>
|
|
</div>
|
|
<div class="peer">
|
|
<small class="ticket-item-datetime"></small>
|
|
</div>
|
|
</div>
|
|
<h5 class="ticket-item-title mb-0"></h5>
|
|
<div class="ticket-item-desc mt-2"></div>
|
|
<div class="peers">
|
|
<div class="ticket-item-priority pe-5 peer peer-greed"></div>
|
|
<div class="ticket-item-tags peer d-flex flex-wrap mw-100"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</script>
|
|
|
|
<!-- Ticket Content Template -->
|
|
<script id="ticketContentTemplate" type="text/template">
|
|
<!-- Header -->
|
|
<div class="ticket-content">
|
|
<div class="peers ai-c jc-sb pX-40 pY-30">
|
|
<div class="peers peer-greed">
|
|
<div class="peer mR-20">
|
|
<img class="ticket-content-icon" src="" alt="">
|
|
</div>
|
|
<div class="peer">
|
|
<small class="ticket-content-datetime"></small>
|
|
<h5 class="ticket-content-author"></h5>
|
|
<div class="ticket-content-badges"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Content -->
|
|
<div class="bdT pX-40 pY-30">
|
|
<h4 class="ticket-content-title"></h4>
|
|
<div class="ticket-content-desc w-100"></div>
|
|
</div>
|
|
</div>
|
|
</script>
|
|
|
|
<!-- Ticket Content Badge Template -->
|
|
<script id="ticketContentBadgeTemplate" type=text/template>
|
|
<div class="ticket-content-badge badge rounded-pill mT-15 me-2">
|
|
<span class="ticket-content-badge-text"></span>
|
|
<i class="ticket-content-badge-icon"></i>
|
|
</div>
|
|
</script>
|
|
|
|
<!-- Define Variables -->
|
|
<script>
|
|
const URL_Tickets = "{% url 'api:tickets' %}";
|
|
const URL_NewTicket = "{% url 'ticket-new' %}";
|
|
const URL_FilterCounts = "{% url 'api:filter-counts' %}";
|
|
const CSRFMiddlewareToken = "{{ csrf_token }}";
|
|
const CurrentUserID = "{{ request.user.uuid }}";
|
|
</script>
|
|
<script src="{% static '/js/tickets.js' %}"></script>
|
|
{% endblock javascripts %}
|