[UPDT] PMS: Updated question template CRUD operations to HTMX
This commit is contained in:
@@ -5,26 +5,23 @@
|
||||
<div class="row">
|
||||
<div class="col-12 col-sm-12 col-md-12 col-lg-12">
|
||||
<div class="oh-card p-4" x-data="{showQuestions: true}">
|
||||
<div class="oh-card__header mb-0">
|
||||
<div class="oh-card__header mb-0 ">
|
||||
<a href="#" class="oh-link oh-link--secondary" x-show="showQuestions"
|
||||
@click="showQuestions = false">
|
||||
@click="showQuestions = false" style="margin-left: 19px;">
|
||||
<ion-icon class="me-2" name="eye-off-outline"></ion-icon>
|
||||
{% trans "Hide Questions" %}
|
||||
</a>
|
||||
<a href="#" class="oh-link oh-link--secondary" x-show="!showQuestions"
|
||||
@click="showQuestions = true">
|
||||
@click="showQuestions = true" style="margin-left: 19px;" >
|
||||
<ion-icon class="me-2" name="eye-outline"></ion-icon>
|
||||
{% trans "Show Questions" %}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="oh-card__body" x-show="showQuestions">
|
||||
<!-- start of all question formset -->
|
||||
|
||||
<div class="row d-flex justify-content-between align-items-center">
|
||||
{% for form in form_list %}
|
||||
|
||||
<form action="{% url 'question-update' temp_id=question_template.id q_id=form.instance.id %}"
|
||||
method="post">
|
||||
{% csrf_token %}
|
||||
@@ -41,7 +38,7 @@
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 col-md-12 col-lg-9">
|
||||
<label class="oh-label text-muted fw-bold">{% trans "Question" %}</label>
|
||||
<label class="oh-label text-muted fw-bold" for="id_question">{% trans "Question" %}</label>
|
||||
{% render_field form.question disabled='disabled' %}
|
||||
</div>
|
||||
<div x-data="{showAnswers: true}" class="oh-link__expanded d-none">
|
||||
@@ -59,25 +56,25 @@
|
||||
<div class="row">
|
||||
<div class="col-12 col-sm-12 col-md-6 col-lg-3">
|
||||
<label
|
||||
class="oh-label d-block text-muted fw-bold">{% trans "Option" %}
|
||||
class="oh-label d-block text-muted fw-bold" for="id_option_a">{% trans "Option" %}
|
||||
1</label>
|
||||
{% render_field form.option_a disabled='disabled' %}
|
||||
</div>
|
||||
<div class="col-12 col-sm-12 col-md-6 col-lg-3">
|
||||
<label
|
||||
class="oh-label d-block text-muted fw-bold">{% trans "Option" %}
|
||||
class="oh-label d-block text-muted fw-bold" for="id_option_b">{% trans "Option" %}
|
||||
2</label>
|
||||
{% render_field form.option_b disabled='disabled' %}
|
||||
</div>
|
||||
<div class="col-12 col-sm-12 col-md-6 col-lg-3">
|
||||
<label
|
||||
class="oh-label d-block text-muted fw-bold">{% trans "Option" %}
|
||||
class="oh-label d-block text-muted fw-bold" for="id_option_c">{% trans "Option" %}
|
||||
3</label>
|
||||
{% render_field form.option_c disabled='disabled' %}
|
||||
</div>
|
||||
<div class="col-12 col-sm-12 col-md-6 col-lg-3">
|
||||
<label
|
||||
class="oh-label d-block text-muted fw-bold">{% trans "Option" %}
|
||||
class="oh-label d-block text-muted fw-bold" for="id_option_d">{% trans "Option" %}
|
||||
4</label>
|
||||
{% render_field form.option_d disabled='disabled' %}
|
||||
</div>
|
||||
|
||||
@@ -5,18 +5,7 @@
|
||||
{% block content %}
|
||||
|
||||
<!--start of messages -->
|
||||
{% if messages %}
|
||||
|
||||
<div class="oh-wrapper">
|
||||
{% for message in messages %}
|
||||
<div class="oh-alert-container">
|
||||
<div class="oh-alert oh-alert--animated {{message.tags}}">
|
||||
{{ message }}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<!-- end of messages -->
|
||||
|
||||
|
||||
@@ -133,7 +122,8 @@ $(document).ready(function () {
|
||||
this.submit();
|
||||
}
|
||||
});
|
||||
}); -->
|
||||
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
!-->
|
||||
|
||||
{% endblock %}
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
{% load i18n %} {% load static %} {% load basefilters %}
|
||||
{% if messages %}
|
||||
{% for message in messages %}
|
||||
<div class="oh-wrapper">
|
||||
<div class="oh-alert-container">
|
||||
<div class="oh-alert oh-alert--animated {{message.tags}} ">{{message}}</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif%}
|
||||
{% if question_templates %}
|
||||
<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">{% trans "Title" %}</div>
|
||||
<div class="oh-sticky-table__th">{% trans "Total Question" %}</div>
|
||||
{% if perms.pms.change_questiontemplate or perms.pms.delete_questiontemplate or request.user|filtersubordinates %}
|
||||
<div class="oh-sticky-table__th"></div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="oh-sticky-table__tbody">
|
||||
{% for question_template in question_templates %}
|
||||
<div class="oh-sticky-table__tr" draggable="true">
|
||||
<a
|
||||
style="color: inherit; text-decoration: none"
|
||||
href="{% url 'question-template-detailed-view' template_id=question_template.id %}"
|
||||
class="oh-sticky-table__sd"
|
||||
>
|
||||
<div class="oh-profile oh-profile--md">
|
||||
<div class="oh-profile__avatar mr-1">
|
||||
<img
|
||||
src="https://ui-avatars.com/api/?name={{question_template.question_template}}&background=random"
|
||||
class="oh-profile__image"
|
||||
alt="Mary Magdalene"
|
||||
/>
|
||||
</div>
|
||||
<span class="oh-profile__name oh-text--dark"
|
||||
>{{question_template.question_template}}</span
|
||||
>
|
||||
</div>
|
||||
</a>
|
||||
<a
|
||||
style="color: inherit; text-decoration: none"
|
||||
href="{% url 'question-template-detailed-view' template_id=question_template.id %}"
|
||||
class="oh-sticky-table__td"
|
||||
>{{question_template.question.count}}</a
|
||||
>
|
||||
|
||||
{% if perms.pms.change_questiontemplate or perms.pms.delete_questiontemplate or request.user|filtersubordinates %}
|
||||
<div class="oh-sticky-table__td">
|
||||
<div class="oh-btn-group">
|
||||
{% if perms.pms.change_questiontemplate or request.user|filtersubordinates %}
|
||||
<a
|
||||
class="oh-btn oh-btn--light-bkg w-100"
|
||||
data-toggle="oh-modal-toggle"
|
||||
data-target="#questionTemplateUpdateModal"
|
||||
hx-get="{% url 'question-template-update' template_id=question_template.id %}"
|
||||
title="{% trans 'Update' %}"
|
||||
hx-target="#questionTemplateUpdateModalTarget"
|
||||
>
|
||||
<ion-icon
|
||||
name="create-outline"
|
||||
role="img"
|
||||
class="md hydrated"
|
||||
aria-label="create outline"
|
||||
></ion-icon
|
||||
></a>
|
||||
{% endif %} {% if perms.pms.delete_questiontemplate or request.user|filtersubordinates %}
|
||||
<a
|
||||
class="oh-btn oh-btn--danger-outline w-100"
|
||||
title="{% trans 'Delete' %}"
|
||||
hx-confirm="{% trans 'Do you want to delete this question template?' %}"
|
||||
hx-get="{% url 'question-template-delete' template_id=question_template.id %}"
|
||||
hx-target="#questionTemplateList"
|
||||
>
|
||||
<ion-icon
|
||||
name="trash-outline"
|
||||
role="img"
|
||||
class="md hydrated"
|
||||
aria-label="trash outline"
|
||||
></ion-icon>
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor%}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="oh-wrapper-main">
|
||||
<main :class="sidebarOpen ? 'oh-main__sidebar-visible' : ''">
|
||||
<div class="oh-wrapper">
|
||||
<div class="oh-404">
|
||||
<img style=" width: 190px;height: 190px;" src="{% static 'images/ui/editor.png' %}" class="oh-404__image mb-4" alt="Page not found. 404."/>
|
||||
<h5 class="oh-404__subtitle">{% trans "No Question templates are available." %}</h5>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
{% endif %}
|
||||
@@ -1,5 +1,21 @@
|
||||
{% load i18n %}
|
||||
<form method="post" action="{% url 'question-template-update' template_id=question_update_form.instance.id %}">
|
||||
{% if messages %}
|
||||
<div class="oh-wrapper">
|
||||
{% for message in messages %}
|
||||
<div class="oh-alert-container">
|
||||
<div class="oh-alert oh-alert--animated {{message.tags}}">
|
||||
{{ message }}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
<script>
|
||||
setTimeout(function () {
|
||||
$('.oh-modal__close').click()
|
||||
}, 1000);
|
||||
</script>
|
||||
</div>
|
||||
{% endif %}
|
||||
<form hx-post="{% url 'question-template-update' template_id=question_update_form.instance.id %}" hx-target="#questionTemplateUpdateModalTarget">
|
||||
{% csrf_token %}
|
||||
<div class="oh-modal__dialog-body m-2">
|
||||
<div class="oh-input__group">
|
||||
|
||||
@@ -45,55 +45,11 @@
|
||||
</div>
|
||||
</section>
|
||||
<div class="oh-wrapper">
|
||||
<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">{% trans "Title" %}</div>
|
||||
<div class="oh-sticky-table__th">{% trans "Total Question" %}</div>
|
||||
{% if perms.pms.change_questiontemplate or perms.pms.delete_questiontemplate or request.user|filtersubordinates %}
|
||||
<div class="oh-sticky-table__th"></div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="oh-sticky-table__tbody">
|
||||
{% for question_template in question_templates %}
|
||||
<div class="oh-sticky-table__tr" draggable="true">
|
||||
<a style="color: inherit;text-decoration: none;"
|
||||
href="{% url 'question-template-detailed-view' template_id=question_template.id %}" class="oh-sticky-table__sd">
|
||||
<div class="oh-profile oh-profile--md">
|
||||
<div class="oh-profile__avatar mr-1">
|
||||
<img src="https://ui-avatars.com/api/?name={{question_template.question_template}}&background=random"
|
||||
class="oh-profile__image" alt="Mary Magdalene" />
|
||||
</div>
|
||||
<span class="oh-profile__name oh-text--dark">{{question_template.question_template}}</span>
|
||||
</div>
|
||||
</a>
|
||||
<a style="color: inherit;text-decoration: none;"
|
||||
href="{% url 'question-template-detailed-view' template_id=question_template.id %}"
|
||||
class="oh-sticky-table__td">{{question_template.question.count}}</a>
|
||||
|
||||
{% if perms.pms.change_questiontemplate or perms.pms.delete_questiontemplate or request.user|filtersubordinates %}
|
||||
<div class="oh-sticky-table__td">
|
||||
<div class="oh-btn-group ">
|
||||
{% if perms.pms.change_questiontemplate or request.user|filtersubordinates %}
|
||||
<a class="oh-btn oh-btn--light-bkg w-100 " data-toggle="oh-modal-toggle" data-target="#questionTemplateUpdateModal"
|
||||
hx-get="{% url 'question-template-update' template_id=question_template.id %}" title="{% trans 'Update' %}" hx-target="#questionTemplateUpdateModalTarget" > <ion-icon
|
||||
name="create-outline" role="img" class="md hydrated" aria-label="create outline"></ion-icon></a>
|
||||
{% endif %}
|
||||
{% if perms.pms.delete_questiontemplate or request.user|filtersubordinates %}
|
||||
<a class="oh-btn oh-btn--danger-outline w-100" title="{% trans 'Delete' %}" onclick="return confirm('{% trans "Do you want to delete this question template?" %}')" href="{% url 'question-template-delete' template_id=question_template.id %}">
|
||||
<ion-icon name="trash-outline" role="img" class="md hydrated" aria-label="trash outline"></ion-icon>
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor%}
|
||||
</div>
|
||||
</div>
|
||||
<!-- question template table start -->
|
||||
<div id="questionTemplateList">
|
||||
{% include "feedback/question_template/question_template_list.html" %}
|
||||
</div>
|
||||
<!-- question template table end -->
|
||||
|
||||
<!-- question template create modal start -->
|
||||
<div class="oh-modal" id="questionTemplateModal" role="dialog" aria-labelledby="questionTemplateModal"
|
||||
@@ -132,18 +88,17 @@
|
||||
aria-hidden="true">
|
||||
<div class="oh-modal__dialog " >
|
||||
<div class="oh-modal__dialog-header">
|
||||
<span class="oh-modal__dialog-title" id="addEmployeeModalLabel">{% trans "Question Template" %}</span>
|
||||
<button type="button" class="oh-modal__close" aria-label="Close">
|
||||
<span class="oh-modal__dialog-title" id="questionTemplateUpdateModalLabel">{% trans "Question Template" %}</span>
|
||||
<button type="button" class="oh-modal__close" aria-label="Close"
|
||||
hx-get="{% url 'question-template-hx-view' %}" hx-target="#questionTemplateList"
|
||||
>
|
||||
<ion-icon name="close-outline"></ion-icon>
|
||||
</button>
|
||||
</div>
|
||||
<div id="questionTemplateUpdateModalTarget">
|
||||
|
||||
</div>
|
||||
|
||||
<div id="questionTemplateUpdateModalTarget"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- question template modal end -->
|
||||
</div> <!-- question template modal end -->
|
||||
</main>
|
||||
|
||||
<script>
|
||||
|
||||
@@ -136,6 +136,11 @@ urlpatterns = [
|
||||
views.question_template_view,
|
||||
name="question-template-view",
|
||||
),
|
||||
path(
|
||||
"question-template-hx-view",
|
||||
views.question_template_hx_view,
|
||||
name="question-template-hx-view",
|
||||
),
|
||||
path(
|
||||
"question-template-detailed-view/<int:template_id>",
|
||||
views.question_template_detailed_view,
|
||||
|
||||
40
pms/views.py
40
pms/views.py
@@ -1619,11 +1619,22 @@ def question_template_view(request):
|
||||
"""
|
||||
question_templates = QuestionTemplate.objects.all()
|
||||
context = {"form": QuestionTemplateForm, "question_templates": question_templates}
|
||||
if question_templates.exists():
|
||||
template = "feedback/question_template/question_template_view.html"
|
||||
else:
|
||||
template = "feedback/question_template/question_template_empty.html"
|
||||
return render(request, template, context)
|
||||
return render(
|
||||
request, "feedback/question_template/question_template_view.html", context
|
||||
)
|
||||
|
||||
|
||||
@login_required
|
||||
@manager_can_enter(perm="pms.view_questiontemplate")
|
||||
def question_template_hx_view(request):
|
||||
"""
|
||||
This view is used to view question template object in htmx.
|
||||
"""
|
||||
question_templates = QuestionTemplate.objects.all()
|
||||
context = {"question_templates": question_templates}
|
||||
return render(
|
||||
request, "feedback/question_template/question_template_list.html", context
|
||||
)
|
||||
|
||||
|
||||
@login_required
|
||||
@@ -1638,8 +1649,11 @@ def question_template_detailed_view(request, template_id, **kwargs):
|
||||
it will redirect to question_template_detailed_view.
|
||||
"""
|
||||
|
||||
question_template = QuestionTemplate.objects.get(id=template_id)
|
||||
questions = question_template.question.all()
|
||||
question_template = QuestionTemplate.objects.filter(id=template_id).first()
|
||||
if not question_template:
|
||||
messages.error(request, _("Question template does not exist"))
|
||||
return redirect(question_template_view)
|
||||
questions = question_template.question.all().order_by("-id")
|
||||
question_types = ["text", "ratings", "boolean", "multi-choices", "likert"]
|
||||
options = QuestionOptions.objects.filter(question_id__in=questions)
|
||||
|
||||
@@ -1679,7 +1693,7 @@ def question_template_update(request, template_id):
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
messages.info(request, _("Question template updated"))
|
||||
return redirect(question_template_view)
|
||||
# return redirect(question_template_view)
|
||||
context["question_update_form"] = form
|
||||
return render(
|
||||
request, "feedback/question_template/question_template_update.html", context
|
||||
@@ -1700,14 +1714,16 @@ def question_template_delete(request, template_id):
|
||||
question_template = QuestionTemplate.objects.get(id=template_id)
|
||||
if Feedback.objects.filter(question_template_id=question_template):
|
||||
messages.info(request, _("This template is using in a feedback"))
|
||||
return redirect(question_template_view)
|
||||
question_template.delete()
|
||||
messages.success(request, _("The question template is deleted successfully !."))
|
||||
else:
|
||||
question_template.delete()
|
||||
messages.success(
|
||||
request, _("The question template is deleted successfully !.")
|
||||
)
|
||||
except QuestionTemplate.DoesNotExist:
|
||||
messages.error(request, _("question template not found."))
|
||||
except ProtectedError:
|
||||
messages.error(request, _("Related entries exists"))
|
||||
return redirect(question_template_view)
|
||||
return redirect("question-template-hx-view")
|
||||
|
||||
|
||||
@login_required
|
||||
|
||||
Reference in New Issue
Block a user