[UPDT] HELPDESK: Helpdesk module style updates and fixes
This commit is contained in:
@@ -3,70 +3,68 @@
|
||||
{% if faq_categories %}
|
||||
<div class="oh-faq-cards grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-3 p-2">
|
||||
{% for category in faq_categories %}
|
||||
<div class="shadow-card p-5 bg-white rounded-md border border-dark-50" id="faqCategoryItem{{category.id}}">
|
||||
<div class="flex justify-between items-start mb-4">
|
||||
<h3 class="text-md font-semibold">{{ category.title }}</h3>
|
||||
<div class="shadow-card p-5 bg-white rounded-md border border-dark-50 flex flex-col justify-between h-full" id="faqCategoryItem{{category.id}}">
|
||||
<div class="flex flex-col flex-grow">
|
||||
<div class="flex justify-between items-start mb-4">
|
||||
<h3 class="text-md font-semibold">{{ category.title }}</h3>
|
||||
|
||||
{% if perms.helpdesk.change_faqcategory or perms.helpdesk.delete_faqcategory %}
|
||||
<div class="relative inline-block dropdown-wrapper" x-data="{ open: false }">
|
||||
<a class="cursor-pointer dropdown-toggle" @click="open = !open" @click.outside="open = false">
|
||||
<i class="fa-solid fa-ellipsis-vertical text-black"></i>
|
||||
</a>
|
||||
<!-- Dropdown Content -->
|
||||
<div
|
||||
class="oh-dropdown__menu oh-dropdown__menu--right"
|
||||
x-show="open"
|
||||
style="min-width:135px;"
|
||||
>
|
||||
<ul class="oh-dropdown__items">
|
||||
{% if perms.helpdesk.change_faqcategory %}
|
||||
<li class="oh-dropdown__item">
|
||||
<a
|
||||
hx-get="{% url 'faq-category-update' category.id %}"
|
||||
hx-target="#objectCreateModalTarget"
|
||||
data-toggle="oh-modal-toggle"
|
||||
data-target="#objectCreateModal"
|
||||
role="button"
|
||||
class="oh-dropdown__link"
|
||||
>{% trans "Edit" %}</a
|
||||
>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if perms.helpdesk.delete_faqcategory %}
|
||||
<li class="oh-dropdown__item">
|
||||
<form
|
||||
hx-confirm="{% trans 'Are you sure you want to delete this FAQ Category?' %}"
|
||||
hx-post="{% url 'faq-category-delete' category.id %}"
|
||||
hx-swap="outerHTML"
|
||||
hx-on-htmx-after-request="setTimeout(() => {reloadMessage(this);},100);"
|
||||
hx-target="#faqCategoryItem{{category.id}}"
|
||||
>
|
||||
{% csrf_token %}
|
||||
<button
|
||||
type="submit"
|
||||
class="oh-dropdown__link oh-dropdown__link--danger"
|
||||
{% if perms.helpdesk.change_faqcategory or perms.helpdesk.delete_faqcategory %}
|
||||
<div class="relative inline-block dropdown-wrapper" x-data="{ open: false }">
|
||||
<a class="cursor-pointer dropdown-toggle" @click="open = !open" @click.outside="open = false">
|
||||
<i class="fa-solid fa-ellipsis-vertical text-black"></i>
|
||||
</a>
|
||||
<div
|
||||
class="oh-dropdown__menu oh-dropdown__menu--right"
|
||||
x-show="open"
|
||||
style="min-width:135px;"
|
||||
>
|
||||
<ul class="oh-dropdown__items">
|
||||
{% if perms.helpdesk.change_faqcategory %}
|
||||
<li class="oh-dropdown__item">
|
||||
<a
|
||||
hx-get="{% url 'faq-category-update' category.id %}"
|
||||
hx-target="#objectCreateModalTarget"
|
||||
data-toggle="oh-modal-toggle"
|
||||
data-target="#objectCreateModal"
|
||||
role="button"
|
||||
class="oh-dropdown__link"
|
||||
>{% trans "Edit" %}</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if perms.helpdesk.delete_faqcategory %}
|
||||
<li class="oh-dropdown__item">
|
||||
<form
|
||||
hx-confirm="{% trans 'Are you sure you want to delete this FAQ Category?' %}"
|
||||
hx-post="{% url 'faq-category-delete' category.id %}"
|
||||
hx-swap="outerHTML"
|
||||
hx-on-htmx-after-request="setTimeout(() => {reloadMessage(this);},100);"
|
||||
hx-target="#faqCategoryItem{{category.id}}"
|
||||
>
|
||||
{% trans "Delete" %}
|
||||
</button>
|
||||
</form>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
{% csrf_token %}
|
||||
<button
|
||||
type="submit"
|
||||
class="oh-dropdown__link oh-dropdown__link--danger"
|
||||
>
|
||||
{% trans "Delete" %}
|
||||
</button>
|
||||
</form>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<p class="text-sm text-[#565E6C] mb-3 flex-grow">{{ category.description | linebreaksbr }}</p>
|
||||
</div>
|
||||
|
||||
<p class="text-sm text-[#565E6C] mb-3">{{ category.description }}</p>
|
||||
|
||||
<a
|
||||
href="{% url 'faq-view' category.id %}"
|
||||
class="px-5 py-2 group text-primary-600 text-xs font-medium bg-primary-100 rounded-md w-full hover:bg-primary-600 hover:text-white transition duration-300 flex items-center justify-center"
|
||||
class="px-5 py-2 mt-auto group text-primary-600 text-xs font-medium bg-primary-100 rounded-md w-full hover:bg-primary-600 hover:text-white transition duration-300 flex items-center justify-center"
|
||||
>
|
||||
{% trans "View FAQs" %}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
|
||||
@@ -1,4 +1,32 @@
|
||||
{% load i18n %} {% load static %}
|
||||
<style>
|
||||
.oh-faq__input-search {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.ui-autocomplete {
|
||||
position: absolute !important;
|
||||
top: 100% !important;
|
||||
left: 0 !important;
|
||||
width: 100% !important;
|
||||
z-index: 9999 !important;
|
||||
background-color: white !important;
|
||||
border: 1px solid #e5e7eb !important;
|
||||
border-radius: 0.375rem !important;
|
||||
box-shadow: 0 4px 10px rgba(0,0,0,0.05) !important;
|
||||
padding: 0.25rem 0 !important;
|
||||
}
|
||||
|
||||
.ui-autocomplete li {
|
||||
padding: 6px 10px !important;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.ui-autocomplete li:hover {
|
||||
background-color: #f3f4f6 !important;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
<section class="oh-wrapper mb-3 p-3">
|
||||
<div class="flex flex-wrap justify-between items-center">
|
||||
|
||||
@@ -11,7 +39,7 @@
|
||||
<div class="flex items-center flex-wrap gap-2">
|
||||
|
||||
<!-- Search Input -->
|
||||
<div class="relative" :class="searchShow ? 'block' : 'hidden md:block'">
|
||||
<div class="relative oh-faq__input-search" :class="searchShow ? 'block' : 'hidden md:block'">
|
||||
<input type="text"
|
||||
name="search"
|
||||
placeholder="{% trans 'Search in FAQs...' %}"
|
||||
|
||||
@@ -107,9 +107,9 @@
|
||||
x-bind:style="open ? 'max-height:' + $refs.panel.scrollHeight + 'px' : 'max-height:0'"
|
||||
>
|
||||
<div class="py-3">
|
||||
<p class="text-sm text-[#565E6C]">
|
||||
{{ faq.answer|safe }}
|
||||
</p>
|
||||
<div class="text-sm text-[#565E6C]">
|
||||
{{ faq.answer|linebreaksbr }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -13,20 +13,29 @@
|
||||
<form
|
||||
hx-post="{{request.path}}"
|
||||
hx-target="#objectCreateModalTarget"
|
||||
class="p-6"
|
||||
>
|
||||
{% csrf_token %}
|
||||
<div
|
||||
class="oh-checkpoint-badge text-success mb-2 selectFaqs"
|
||||
style="cursor: pointer"
|
||||
>
|
||||
{% trans "Select All Faqs" %}
|
||||
</div>
|
||||
<div
|
||||
class="oh-checkpoint-badge text-secondary mb-2 unSelectFaqs"
|
||||
style="cursor: pointer"
|
||||
>
|
||||
{% trans "Unselect All Faqs" %}
|
||||
|
||||
<div class="d-flex gap-2 mb-3">
|
||||
<button
|
||||
type="button"
|
||||
class="px-4 py-2 bg-primary-600 text-white rounded-md text-xs hover:bg-primary-800 transition duration-300 selectFaqs"
|
||||
>
|
||||
<ion-icon name="checkmark-done-outline" class="me-1"></ion-icon>
|
||||
{% trans "Select All Faqs" %}
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
class="px-4 py-2 bg-[#720c80] text-white rounded-md text-xs hover:bg-primary-800 transition duration-300 unSelectFaqs"
|
||||
>
|
||||
<ion-icon name="close-circle-outline" class="me-1"></ion-icon>
|
||||
{% trans "Unselect All Faqs" %}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="space-y-2 mb-4">
|
||||
<!-- Accordion Item -->
|
||||
{% for cat_id, category in catagories.items %}
|
||||
@@ -57,7 +66,7 @@
|
||||
</span>
|
||||
|
||||
<div
|
||||
class="grid grid-cols-1 lg:grid-cols-2 gap-3 p-2 h-60 overflow-hidden overflow-y-auto"
|
||||
class="grid grid-cols-1 lg:grid-cols-2 gap-3 p-2 h-60 overflow-hidden overflow-y-auto faqs-list"
|
||||
>
|
||||
{% for faq in faqs %}
|
||||
{% if faq.fields.category == cat_id %}
|
||||
@@ -110,3 +119,20 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
$(".selectAll").click(function () {
|
||||
var isChecked = $(this).prop("checked");
|
||||
$(this).parent().siblings(".faqs-list").find(".custom-radio-checkmark").prop("checked", isChecked);
|
||||
});
|
||||
$(".selectFaqs").click(function () {
|
||||
$(".selectAll").prop("checked", false);
|
||||
$(".selectAll").click();
|
||||
});
|
||||
$(".unSelectFaqs").click(function () {
|
||||
$(".selectAll").prop("checked", true);
|
||||
$(".selectAll").click();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
{% load i18n %}
|
||||
<div class="oh-modal__dialog-header">
|
||||
<button class="oh-modal__close top-[5px] right-[5px]" aria-label="Close">
|
||||
<span class="text-md font-semibold mb-3" id="shiftRequestDetailModalLabel">
|
||||
{% trans "Responsibility" %}
|
||||
</span>
|
||||
<button class="oh-modal__close" aria-label="Close">
|
||||
<ion-icon name="close-outline"></ion-icon>
|
||||
</button>
|
||||
</div>
|
||||
@@ -18,12 +21,13 @@
|
||||
>
|
||||
{{form.non_field_errors}} {{form.assigned_to}}
|
||||
</div>
|
||||
<button
|
||||
type="submit"
|
||||
class="oh-btn oh-d-hide oh-btn--small oh-btn--secondary oh-btn--add-advanced-tab w-100 mt-3 mb-2"
|
||||
>
|
||||
<ion-icon class="me-1" name="save-outline"></ion-icon>
|
||||
{% trans 'Save Changes' %}
|
||||
</button>
|
||||
<div class="flex justify-end">
|
||||
<button
|
||||
type="submit"
|
||||
class="oh-btn oh-d-hide oh-btn--small oh-btn--secondary oh-btn--add-advanced-tab w-100 mt-3 mb-2"
|
||||
>
|
||||
{% trans 'Save' %}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% load i18n %}
|
||||
<div class="oh-modal__dialog-header">
|
||||
<span class="oh-modal__dialog-title" id="shiftRequestDetailModalLabel">
|
||||
<span class="text-md font-semibold mb-3" id="shiftRequestDetailModalLabel">
|
||||
{% trans "Responsibility" %}
|
||||
</span>
|
||||
<button class="oh-modal__close" aria-label="Close">
|
||||
@@ -21,23 +21,24 @@
|
||||
<div class="oh-input-group">
|
||||
{{form.non_field_errors}}
|
||||
<label
|
||||
class="oh-input__label"
|
||||
class="oh-label"
|
||||
for="{{form.assigning_type.id_for_label}}"
|
||||
>{{form.assigning_type.label}}</label
|
||||
>
|
||||
{{form.assigning_type}}
|
||||
<label class="oh-input__label" for="{{form.raised_on.id_for_label}}"
|
||||
<label class="oh-label" for="{{form.raised_on.id_for_label}}"
|
||||
>{{form.raised_on.label}}</label
|
||||
>
|
||||
{{form.raised_on}}
|
||||
</div>
|
||||
<button
|
||||
type="submit"
|
||||
class="oh-btn oh-d-hide oh-btn--small oh-btn--secondary oh-btn--add-advanced-tab w-100 mt-3 mb-2"
|
||||
>
|
||||
<ion-icon class="me-1" name="save-outline"></ion-icon>
|
||||
{% trans 'Save Changes' %}
|
||||
</button>
|
||||
<div class="flex justify-end">
|
||||
<button
|
||||
type="submit"
|
||||
class="oh-btn oh-d-hide oh-btn--small oh-btn--secondary oh-btn--add-advanced-tab w-100 mt-3 mb-2"
|
||||
>
|
||||
{% trans 'Save' %}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
{% load static %}{% load i18n %}
|
||||
<script>
|
||||
$("#reloadMessagesButton").click()
|
||||
</script>
|
||||
|
||||
<div class="oh-card bg-white rounded-md shadow-md p-5">
|
||||
<!-- Modal Header -->
|
||||
<div class="flex justify-between items-center mb-5 border-b border-gray-200 pb-3 relative">
|
||||
<h1 class="text-lg font-semibold text-gray-800">
|
||||
{% trans "Claim Requests" %}
|
||||
</h1>
|
||||
<button
|
||||
type="button"
|
||||
class="oh-modal__close absolute top-0 right-0 text-gray-600 hover:text-gray-900"
|
||||
data-dismiss="oh-modal"
|
||||
aria-label="Close"
|
||||
{% if refresh %}
|
||||
onclick="event.stopPropagation(); window.location.reload();"
|
||||
{% endif %}
|
||||
>
|
||||
<ion-icon name="close-outline" class="text-2xl"></ion-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
{% if claim_requests %}
|
||||
<!-- List View Table -->
|
||||
<div class="overflow-hidden bg-white border border-gray-200 rounded-md">
|
||||
<table class="min-w-full divide-y divide-gray-100">
|
||||
<thead class="bg-gray-50 text-xs font-medium text-gray-600 uppercase tracking-wider">
|
||||
<tr>
|
||||
<th scope="col" class="px-6 py-3 text-left">{% trans "Employee" %}</th>
|
||||
<th scope="col" class="px-6 py-3 text-center w-32">{% trans "Action" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody class="divide-y divide-gray-100 text-sm text-gray-700">
|
||||
{% for req in claim_requests %}
|
||||
<tr class="hover:bg-gray-50 transition">
|
||||
<!-- Employee -->
|
||||
<td class="px-6 py-3 flex items-center gap-3">
|
||||
<img
|
||||
src="{{ req.employee_id.get_avatar }}"
|
||||
alt="{{ req.employee_id }}"
|
||||
class="w-9 h-9 rounded-full object-cover"
|
||||
/>
|
||||
<span class="font-medium">{{ req.employee_id }}</span>
|
||||
</td>
|
||||
|
||||
<!-- Actions -->
|
||||
<td class="px-6 py-3 text-center">
|
||||
<div class="flex justify-center gap-2">
|
||||
{% if not req.is_approved and not req.is_rejected %}
|
||||
<button
|
||||
class="oh-btn oh-btn--success flex items-center justify-center"
|
||||
data-toggle="oh-modal-toggle"
|
||||
data-target="#objectDetailsModal"
|
||||
hx-get="{% url 'approve-claim-request' req.id %}?approve=True"
|
||||
hx-target="#objectDetailsModalTarget"
|
||||
title="{% trans 'Approve request' %}"
|
||||
>
|
||||
<ion-icon name="checkmark-outline"></ion-icon>
|
||||
</button>
|
||||
{% else %}
|
||||
<button
|
||||
class="oh-btn oh-btn--success flex items-center justify-center opacity-50 cursor-not-allowed"
|
||||
disabled
|
||||
title="{% trans 'Approved' %}"
|
||||
>
|
||||
<ion-icon name="checkmark-outline"></ion-icon>
|
||||
</button>
|
||||
{% endif %}
|
||||
|
||||
{% if not req.is_rejected %}
|
||||
<button
|
||||
class="oh-btn oh-btn--danger flex items-center justify-center"
|
||||
data-toggle="oh-modal-toggle"
|
||||
data-target="#objectDetailsModal"
|
||||
hx-get="{% url 'approve-claim-request' req.id %}?approve=False"
|
||||
hx-target="#objectDetailsModalTarget"
|
||||
title="{% trans 'Reject request' %}"
|
||||
>
|
||||
<ion-icon name="close-outline"></ion-icon>
|
||||
</button>
|
||||
{% else %}
|
||||
<button
|
||||
class="oh-btn oh-btn--danger flex items-center justify-center opacity-50 cursor-not-allowed"
|
||||
disabled
|
||||
title="{% trans 'Rejected' %}"
|
||||
>
|
||||
<ion-icon name="close-outline"></ion-icon>
|
||||
</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% else %}
|
||||
<!-- Empty State -->
|
||||
<div class="flex flex-col items-center justify-center h-[60vh] text-center rounded-md">
|
||||
<img
|
||||
src="{% static 'images/ui/ticket.png' %}"
|
||||
alt="No requests"
|
||||
class="w-32 h-32 mb-4 opacity-80"
|
||||
/>
|
||||
<h3 class="text-gray-700 text-base font-medium">
|
||||
{% trans "There are no claim requests at the moment." %}
|
||||
</h3>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
@@ -298,6 +298,21 @@
|
||||
<div
|
||||
class="bg-white rounded-md shadow-card p-3"
|
||||
>
|
||||
<div class="flex justify-end">
|
||||
{% if perms.helpdesk.change_ticket or request.user.employee_get|is_department_manager:ticket %}
|
||||
<button
|
||||
class="p-3 w-100 h-6 mb-2 rounded-md bg-primary-600 flex items-center justify-center text-white text-xs transition duration-300 hover:bg-primary-700"
|
||||
title="{% trans 'Edit Ticket' %}"
|
||||
data-toggle="oh-modal-toggle"
|
||||
data-target="#objectCreateModal"
|
||||
hx-get="{% url 'ticket-update' ticket.id %}"
|
||||
hx-target="#objectCreateModalTarget"
|
||||
>
|
||||
<i class="fa-solid fa-pen"></i>
|
||||
<span class="ms-2 text-sm font-semibold">{% trans "Edit" %}</span>
|
||||
</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div
|
||||
class="h-[80%] lg:h-[calc(100%_-_55px)]"
|
||||
>
|
||||
@@ -326,7 +341,7 @@
|
||||
{% for item in sorted_activity_list %}
|
||||
{% if item.type == 'comment' %}
|
||||
{% if item.comment.employee_id == ticket.employee_id %}
|
||||
<div class="w-full flex justify-end mb-3">
|
||||
{% comment %} <div class="w-full flex justify-end mb-3">
|
||||
<div
|
||||
class="bg-[#26bf941a] p-5 rounded-2xl max-w-[90%] md:w-[60%] mb-3 md:mb-1"
|
||||
>
|
||||
@@ -350,6 +365,19 @@
|
||||
<span class="text-sm text-[#333]">
|
||||
{{item.comment.comment|safe}}
|
||||
</span>
|
||||
<div class="oh-btn-group" style="border:none">
|
||||
{% if request.user.employee_get|is_department_manager:ticket or perms.helpdesk.change_comment or request.user.employee_get == item.comment.employee_id %}
|
||||
<a class="oh-btn p-3 edit_comment" title="{% trans 'Edit' %}">
|
||||
<ion-icon name="pencil-outline"></ion-icon>
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if perms.helpdesk.delete_comment %}
|
||||
<a href="{% url "comment-delete" item.comment.id %}" type="button"
|
||||
title="{% trans 'Delete' %}" class="oh-btn p-3 text-danger">
|
||||
<ion-icon name="trash-outline"></ion-icon>
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="w-[80%] overflow-x-auto flex mt-3">
|
||||
{% if item.comment.comment_attachment.all %}
|
||||
@@ -382,12 +410,17 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> {% endcomment %}
|
||||
<div class="w-full flex justify-end mb-3">
|
||||
<div
|
||||
class="bg-[#26bf941a] p-5 rounded-2xl max-w-[90%] md:w-[60%] mb-3 md:mb-1"
|
||||
>
|
||||
{% else %}
|
||||
<div class="w-full flex justify-start mb-3">
|
||||
<div
|
||||
class="bg-[#d944bb1a] p-5 rounded-2xl max-w-[90%] md:w-[60%] mb-3 md:mb-1"
|
||||
>
|
||||
{% endif %}
|
||||
<div
|
||||
class="flex flex-wrap items-center justify-between mb-3"
|
||||
>
|
||||
@@ -458,7 +491,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% comment %} {% endif %} {% endcomment %}
|
||||
{% elif item.type == 'history' %}
|
||||
{% if item.history.type == 'Ticket created' %}
|
||||
<p class="text-sm text-[#0E79DC] mb-2">
|
||||
|
||||
Reference in New Issue
Block a user