[UPDT] HELPDESK: Helpdesk module style updates and fixes

This commit is contained in:
Horilla
2025-10-15 12:36:46 +05:30
parent 645e8194d6
commit edea20aed6
8 changed files with 294 additions and 90 deletions

View File

@@ -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 %}

View File

@@ -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...' %}"

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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">