[UPDT] HELPDESK: Updated helpdesk app by update model and form class by adding verbose name

This commit is contained in:
Horilla
2025-04-22 11:52:36 +05:30
parent 47eaa2a284
commit c37cd20975
13 changed files with 196 additions and 289 deletions

View File

@@ -46,13 +46,13 @@ TICKET_STATUS = [
class DepartmentManager(HorillaModel):
manager = models.ForeignKey(
Employee,
verbose_name="Manager",
verbose_name=_("Manager"),
related_name="dep_manager",
on_delete=models.CASCADE,
)
department = models.ForeignKey(
Department,
verbose_name="Department",
verbose_name=_("Department"),
related_name="dept_manager",
on_delete=models.CASCADE,
)
@@ -63,6 +63,8 @@ class DepartmentManager(HorillaModel):
class Meta:
unique_together = ("department", "manager")
verbose_name = _("Department Manager")
verbose_name_plural = _("Department Managers")
def clean(self, *args, **kwargs):
super().clean(*args, **kwargs)
@@ -71,9 +73,9 @@ class DepartmentManager(HorillaModel):
class TicketType(HorillaModel):
title = models.CharField(max_length=100, unique=True)
type = models.CharField(choices=TICKET_TYPES, max_length=50)
prefix = models.CharField(max_length=3, unique=True)
title = models.CharField(max_length=100, unique=True, verbose_name=_("Title"))
type = models.CharField(choices=TICKET_TYPES, max_length=50, verbose_name=_("Type"))
prefix = models.CharField(max_length=3, unique=True, verbose_name=_("Prefix"))
company_id = models.ForeignKey(
Company, null=True, editable=False, on_delete=models.PROTECT
)
@@ -82,6 +84,10 @@ class TicketType(HorillaModel):
def __str__(self):
return self.title
class Meta:
verbose_name = _("Ticket Type")
verbose_name_plural = _("Ticket Types")
class Ticket(HorillaModel):
@@ -98,8 +104,10 @@ class Ticket(HorillaModel):
priority = models.CharField(choices=PRIORITY, max_length=100, default="low")
created_date = models.DateField(auto_now_add=True)
resolved_date = models.DateField(blank=True, null=True)
assigning_type = models.CharField(choices=MANAGER_TYPES, max_length=100)
raised_on = models.CharField(max_length=100, verbose_name="Forward To")
assigning_type = models.CharField(
choices=MANAGER_TYPES, max_length=100, verbose_name=_("Assigning Type")
)
raised_on = models.CharField(max_length=100, verbose_name=_("Forward To"))
assigned_to = models.ManyToManyField(
Employee, blank=True, related_name="ticket_assigned_to"
)
@@ -118,6 +126,8 @@ class Ticket(HorillaModel):
class Meta:
ordering = ["-created_date"]
verbose_name = _("Ticket")
verbose_name_plural = _("Tickets")
def clean(self, *args, **kwargs):
super().clean(*args, **kwargs)
@@ -244,6 +254,10 @@ class FAQCategory(HorillaModel):
def __str__(self):
return self.title
class Meta:
verbose_name = _("FAQ Category")
verbose_name_plural = _("FAQ Categories")
class FAQ(HorillaModel):
question = models.CharField(max_length=255)
@@ -258,6 +272,10 @@ class FAQ(HorillaModel):
def __str__(self):
return self.question
class Meta:
verbose_name = _("FAQ")
verbose_name_plural = _("FAQs")
# updating the faq search index when a new faq is created or deleted

View File

@@ -4,14 +4,14 @@
<div class="oh-inner-sidebar-content">
{% if perms.helpdesk.view_departmentmanager %}
<div class="oh-inner-sidebar-content__header d-flex justify-content-between align-items-center">
<h2 class="oh-inner-sidebar-content__title">{% trans "Department managers" %}</h2>
<h2 class="oh-inner-sidebar-content__title">{{model.get_verbose_name_plural}}</h2>
{% if perms.helpdesk.add_departmentmanager %}
<button
class="oh-btn oh-btn--secondary oh-btn--shadow"
data-toggle="oh-modal-toggle"
data-target="#deparmentManagersModal"
data-target="#objectCreateModal"
hx-get="{% url 'department-manager-create' %}"
hx-target="#deparmentManagersModal"
hx-target="#objectCreateModalTarget"
>
<ion-icon name="add-outline" class="me-1"></ion-icon>
{% trans "Create" %}
@@ -30,40 +30,6 @@
</div>
<!-- start of modals -->
<!-- start of create modal -->
<div
class="oh-modal"
id="deparmentManagersModal"
role="dialog"
aria-labelledby="deparmentManagersModal"
aria-hidden="true"
>
</div>
<!-- end of create modal -->
<!-- start of edit modal -->
<div
class="oh-modal"
id="depatmentManagerEditModal"
role="dialog"
aria-labelledby="depatmentManagerEditModal"
aria-hidden="true"
>
<div class="oh-modal__dialog">
<div class="oh-modal__dialog-header">
<h2 class="oh-modal__dialog-title" id="editModaltitle">
{% trans "Department Manager Update" %}
</h2>
<button class="oh-modal__close" aria-label="Close">
<ion-icon name="close-outline"></ion-icon>
</button>
</div>
<div class="oh-modal__dialog-body" id="departmentManagerEditForm"></div>
</div>
</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){

View File

@@ -4,10 +4,11 @@
<div class="oh-modal__dialog-header pb-0">
<h2 class="oh-modal__dialog-title" id="createModalTitle">
{% if dep_id %}
{% trans "Update Department Manager" %}
{% trans "Update" %}
{% else %}
{% trans "Create Department Manager" %}
{% trans "Create" %}
{% endif %}
{{form.verbose_name}}
</h2>
<button class="oh-modal__close" aria-label="Close">
<ion-icon name="close-outline"></ion-icon>
@@ -15,7 +16,6 @@
</div>
<div class="oh-modal__dialog-body" id="deparmentManagersForm">
{% if form.errors %}
<!-- form errors -->
<div class="oh-wrapper">
<div class="oh-alert-container">
{% for error in form.non_field_errors %}
@@ -26,16 +26,10 @@
</div>
</div>
{% endif %}
<form
{% if dep_id %}
hx-post="{% url 'department-manager-update' dep_id %}"
{% else %}
hx-post="{% url 'department-manager-create' %}"
{% endif %}
hx-target="#deparmentManagersModal"
hx-encoding="multipart/form-data"
class="oh-profile-section"
>
<form {% if dep_id %} hx-post="{% url 'department-manager-update' dep_id %}"
hx-target="#objectUpdateModalTarget" {% else %} hx-post="{% url 'department-manager-create' %}"
hx-target="#objectCreateModalTarget" {% endif %} hx-encoding="multipart/form-data"
class="oh-profile-section">
{% csrf_token %}
{{form.as_p}}
<div class="d-flex flex-row-reverse mt-3">

View File

@@ -23,9 +23,9 @@
{% if perms.helpdesk.change_departmentmanager %}
<a
hx-get="{% url 'department-manager-update' manager.id %}"
hx-target="#deparmentManagersModal"
hx-target="#objectUpdateModalTarget"
data-toggle="oh-modal-toggle"
data-target="#deparmentManagersModal"
data-target="#objectUpdateModal"
type="button"
class="oh-btn oh-btn--light-bkg w-50"
title="{% trans 'Edit' %}"

View File

@@ -12,10 +12,11 @@
<div class="oh-modal__dialog-header pb-0">
<h2 class="oh-modal__dialog-title" id="faqCreateModalLabel">
{% if faq_category %}
{% trans "FAQ category Update" %}
{% trans "Update" %}
{% else %}
{% trans "FAQ category Create" %}
{% trans "Create" %}
{% endif %}
{{form.verbose_name}}
</h2>
<button class="oh-modal__close" aria-label="Close">
<ion-icon name="close-outline"></ion-icon>

View File

@@ -1,7 +1,7 @@
{% load i18n %}
{% include 'filter_tags.html' %}
<div class="oh-wrapper oh-faq-cards">
<div class="oh-faq-cards">
{% for category in faq_categories %}
<div class="oh-faq-card" id="faqCategoryItem{{category.id}}">
<div class="d-flex justify-content-between align-items-center">

View File

@@ -2,7 +2,7 @@
<section class="oh-wrapper oh-main__topbar" x-data="{searchShow: false}">
<div class="oh-main__titlebar oh-main__titlebar--left">
<h1 class="oh-main__titlebar-title fw-bold">
{% trans "FAQ Categories" %}
{{model.get_verbose_name_plural}}
</h1>
<a
class="oh-main__titlebar-search-toggle"

View File

@@ -10,10 +10,11 @@
<div class="oh-modal__dialog-header">
<h2 class="oh-modal__dialog-title" id="faqCreateModalLabel">
{% if faq %}
{% trans "FAQ Update" %}
{% trans "Update" %}
{% else %}
{% trans "FAQ Create" %}
{% trans "Create" %}
{% endif %}
{{form.verbose_name}}
</h2>
<button class="oh-modal__close" aria-label="Close">
<ion-icon name="close-outline"></ion-icon>

View File

@@ -50,7 +50,7 @@
@click="open = !open"
onclick="event.preventDefault()"
>
<ion-icon name="filter" class="mr-1"></ion-icon>{% trans "filter" %}
<ion-icon name="filter" class="mr-1"></ion-icon>{% trans "Filter" %}
</button>
<div
class="oh-dropdown__menu oh-dropdown__menu--right oh-dropdown__filter p-4"

View File

@@ -1,23 +1,17 @@
{% load i18n %}
<div
class="oh-dropdown__menu oh-dropdown__menu--top-align oh-dropdown__filter p-4"
style="right: 57px;bottom:100px;max-width:100px;"
x-data="{open: true}"
x-show="open"
@click.outside="open = false"
>
<form hx-post="{% url 'ticket-change-assignees' ticket_id %}" hx-target="#addTagTarget" hx-encoding="multipart/form-data">
<div class="oh-dropdown__menu oh-dropdown__menu--top-align oh-dropdown__filter p-4"
style="right: 57px;bottom:100px;max-width:100px;" x-data="{open: true}" x-show="open" @click.outside="open = false">
<form hx-post="{% url 'ticket-change-assignees' ticket_id %}" hx-target="#addTagTarget"
hx-encoding="multipart/form-data" class="oh-profile-section pt-0">
{% csrf_token %}
<div class="oh-input-group">
<label for="id_name" class="oh-label">{% trans 'Assignees' %}</label>
{{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="add-circle-outline"></ion-icon>
<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>
</form>

View File

@@ -1,29 +1,25 @@
{% load i18n %}
<div
class="oh-dropdown__menu oh-dropdown__menu--top-align oh-dropdown__filter p-4"
style="right: 57px;bottom:100px"
x-data="{open: true}"
x-show="open"
@click.outside="open = false"
>
<form hx-post="{% url 'ticket-change-raised-on' ticket_id %}" hx-target="#addTagTarget" hx-encoding="multipart/form-data">
<div class="oh-dropdown__menu oh-dropdown__menu--top-align oh-dropdown__filter p-4" style="right: 57px;bottom:100px"
x-data="{open: true}" x-show="open" @click.outside="open = false">
<label for="id_name" class="oh-label" style="font-weight: 700;">{% trans 'Responsibility' %}</label>
<form hx-post="{% url 'ticket-change-raised-on' ticket_id %}" hx-target="#addTagTarget"
hx-encoding="multipart/form-data" class="oh-profile-section">
<div hidden id="cur_raised_on" value="{{form.instance.raised_on}}">
{{form.instance.raised_on}}
</div>
{% csrf_token %}
<div class="oh-input-group">
<label for="id_name" class="oh-label">{% trans 'Responsibility' %}</label>
{{form.non_field_errors}}
<label class="oh-input__label" for="id_assigning_type">{% trans "Assigning type" %}</label>
<label class="oh-input__label"
for="{{form.assigning_type.id_for_label}}">{{form.assigning_type.label}}</label>
{{form.assigning_type}}
<label class="oh-input__label" for="id_raised_on">{% trans "Raised on" %}</label>
<label class="oh-input__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="add-circle-outline"></ion-icon>
<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>
</form>

View File

@@ -1,7 +1,8 @@
{% load i18n %}
<div class="oh-modal__dialog-header">
<h2 class="oh-modal__dialog-title" id="createTitle">
{% if ticket_id %} {% trans "Update Ticket" %} {% else %} {% trans "Create Ticket" %} {% endif %}
{% if ticket_id %} {% trans "Update" %} {% else %} {% trans "Create" %} {% endif %}
{{form.verbose_name}}
</h2>
<button type="button" class="oh-modal__close" aria-label="Close">
<ion-icon name="close-outline"></ion-icon>
@@ -9,9 +10,7 @@
</div>
<!-- htmx form -->
<div
class="oh-modal__dialog-body"
>
<div class="oh-modal__dialog-body">
{% if form.errors %}
<!-- form errors -->
<div class="oh-wrapper">
@@ -27,15 +26,9 @@
<div hidden id="cur_raised_on" value="{{form.instance.raised_on}}">
{{form.instance.raised_on}}
</div>
<form
{% if ticket_id %}
hx-post="{% url 'ticket-update' ticket_id %}"
{% else %}
hx-post="{% url 'ticket-create' %}"
{% endif %}
hx-target="#objectCreateModalTarget"
hx-encoding="multipart/form-data"
>
<form {% if ticket_id %} hx-post="{% url 'ticket-update' ticket_id %}" {% else %}
hx-post="{% url 'ticket-create' %}" {% endif %} hx-target="#objectCreateModalTarget"
hx-encoding="multipart/form-data">
{% csrf_token %} {{form.as_p}}
</form>
</div>
@@ -43,21 +36,15 @@
<div id="addTagModal">
<div id="addTagTarget"></div>
</div>
<div
class="oh-modal"
id="createTagModal"
role="dialog"
aria-labelledby="editDialogModal"
aria-hidden="true"
>
<div class="oh-modal" id="createTagModal" role="dialog" aria-labelledby="editDialogModal" aria-hidden="true">
<div class="oh-modal__dialog">
<div class="oh-modal__dialog-header pb-0">
<h2 class="oh-modal__dialog-title" id="editTitle">
{% trans "Create Tag" %}
</h2>
<button
style="
<button style="
border: none;
background: none;
font-size: 1.5rem;
@@ -68,10 +55,8 @@
cursor: pointer;
-webkit-transition: all 0.3s ease-in-out;
transition: all 0.3s ease-in-out;
"
aria-label="Close"
onclick="event.stopPropagation(); $('#createTagModal').removeClass('oh-modal--show'); $('#id_tags option[value=\'create_new_tag\']').prop('selected', false);"
>
" aria-label="Close"
onclick="event.stopPropagation(); $('#createTagModal').removeClass('oh-modal--show'); $('#id_tags option[value=\'create_new_tag\']').prop('selected', false);">
<ion-icon name="close-outline"></ion-icon>
</button>
</div>
@@ -80,35 +65,14 @@
{% csrf_token %}
<label class="oh-label">{% trans "Title" %}</label>
<input
type="text"
name="title"
maxlength="30"
class="oh-input w-100"
placeholder="Title"
required=""
id="id_tag_title"
/>
<input type="text" name="title" maxlength="30" class="oh-input w-100" placeholder="Title" required=""
id="id_tag_title" />
<label class="oh-label">{% trans "Color" %}</label>
<input
type="color"
name="color"
style="height: 50px"
maxlength="30"
class="oh-input w-100"
placeholder="Color"
required=""
id="id_tag_color"
/>
<input
type="checkbox"
name="is_active"
class="oh-switch__checkbox"
id="id_tag_is_active"
checked
style="display: none"
/>
<input type="color" name="color" style="height: 50px" maxlength="30" class="oh-input w-100"
placeholder="Color" required="" id="id_tag_color" />
<input type="checkbox" name="is_active" class="oh-switch__checkbox" id="id_tag_is_active" checked
style="display: none" />
<div class="oh-modal__dialog-footer p-0 mt-3">
<button type="submit" class="oh-btn oh-btn--secondary oh-btn--shadow">
@@ -125,23 +89,14 @@
<div id="addTicketTypeModal">
<div id="addTicketTypeTarget"></div>
</div>
<div
class="oh-modal"
id="createTicketTypeModal"
role="dialog"
aria-labelledby="editDialogModal"
aria-hidden="true"
>
<div class="oh-modal" id="createTicketTypeModal" role="dialog" aria-labelledby="editDialogModal" aria-hidden="true">
<div class="oh-modal__dialog">
<div class="oh-modal__dialog-header">
<h2 class="oh-modal__dialog-title" id="editTitle">
{% trans "Create Ticket Type" %}
{% trans "Create" %} {{t_type_form.verbose_name}}
</h2>
<button
class="oh-modal__close--custom"
onclick="$('#createTicketTypeModal').removeClass('oh-modal--show')"
aria-label="Close"
>
<button class="oh-modal__close--custom" onclick="$('#createTicketTypeModal').removeClass('oh-modal--show')"
aria-label="Close">
<ion-icon name="close-outline"></ion-icon>
</button>
</div>
@@ -149,34 +104,28 @@
<form onsubmit="saveTicketType();event.preventDefault();" class="oh-profile-section">
{% csrf_token %}
<label class="oh-label">{% trans "Title" %}</label>
<input
type="text"
name="title"
maxlength="30"
class="oh-input w-100"
placeholder="Title"
required=""
id="id_ticket_type_title"
/>
<label class="oh-label">{% trans "Type" %}</label>
<div class="oh-input-group">
<label class="oh-label" for="{{t_type_form.title.id_for_label}}">{{t_type_form.title.label}}</label>
<input type="text" name="title" maxlength="30" class="oh-input w-100" placeholder="Title"
required="" id="id_ticket_type_title" />
</div>
<div class="oh-input-group">
<label class="oh-label" for="{{t_type_form.type.id_for_label}}">{{t_type_form.type.label}}</label>
{{t_type_form.type}}
<label class="oh-label">{% trans "Prefix" %}</label>
</div>
<div class="oh-input-group">
<label class="oh-label"
for="{{t_type_form.prefix.id_for_label}}">{{t_type_form.prefix.label}}</label>
{{t_type_form.prefix}}
<input
type="checkbox"
name="is_active"
class="oh-switch__checkbox"
id="id_ticket_type_is_active"
checked
style="display: none"
/>
</div>
<input type="checkbox" name="is_active" class="oh-switch__checkbox" id="id_ticket_type_is_active"
checked style="display: none" />
<div class="d-flex flex-row-reverse">
<button
type="submit"
class="oh-btn oh-btn--secondary mt-2 mr-0 pl-4 pr-5 oh-btn--w-100-resp"
>
<button type="submit" class="oh-btn oh-btn--secondary mt-2 mr-0 pl-4 pr-5 oh-btn--w-100-resp">
{% trans "Save" %}
</button>
</div>

View File

@@ -82,6 +82,7 @@ def faq_category_view(request):
context = {
"faq_categories": faq_categories,
"f": FAQFilter(request.GET),
"model": FAQCategory,
}
return render(request, "helpdesk/faq/faq_view.html", context=context)
@@ -1491,21 +1492,6 @@ def tickets_bulk_delete(request):
return HttpResponse(script)
@login_required
def add_department_manager(request):
form = DepartmentManagerCreateForm()
if request.method == "POST":
form = DepartmentManagerCreateForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return HttpResponse("<script>window.location.reload()</script>")
context = {
"form": form,
}
return render(request, "helpdesk/faq/department_managers_form.html", context)
@login_required
@hx_request_required
def create_department_manager(request):
@@ -1676,9 +1662,11 @@ def ticket_type_delete(request, t_type_id):
@login_required
@permission_required("helpdesk.view_departmentmanager")
def view_department_managers(request):
department_managers = DepartmentManager.objects.all()
model_class = DepartmentManager
department_managers = model_class.objects.all()
context = {
"model": model_class,
"department_managers": department_managers,
}
return render(request, "department_managers/department_managers.html", context)