[UPDT] HELPDESK: Added load faqs to faq view
This commit is contained in:
@@ -261,8 +261,8 @@ class FAQCategory(HorillaModel):
|
||||
|
||||
class FAQ(HorillaModel):
|
||||
question = models.CharField(max_length=255)
|
||||
answer = models.TextField(max_length=255)
|
||||
tags = models.ManyToManyField(Tags)
|
||||
answer = models.TextField()
|
||||
tags = models.ManyToManyField(Tags, blank=True)
|
||||
category = models.ForeignKey(FAQCategory, on_delete=models.PROTECT)
|
||||
company_id = models.ForeignKey(
|
||||
Company, null=True, editable=False, on_delete=models.PROTECT
|
||||
|
||||
@@ -47,6 +47,39 @@
|
||||
</select>
|
||||
{% endcomment %}
|
||||
</div>
|
||||
<div class="oh-accordion-meta__actions" onclick="event.stopPropagation()">
|
||||
<div class="oh-dropdown" x-data="{open: false}">
|
||||
<button
|
||||
class="oh-btn oh-stop-prop oh-accordion-meta__btn"
|
||||
@click="open = !open"
|
||||
@click.outside="open = false"
|
||||
>
|
||||
{% trans "Actions" %}
|
||||
<ion-icon
|
||||
class="ms-2 oh-accordion-meta__btn-icon"
|
||||
name="caret-down-outline"
|
||||
></ion-icon>
|
||||
</button>
|
||||
<div
|
||||
class="oh-dropdown__menu oh-dropdown__menu--right"
|
||||
x-show="open"
|
||||
>
|
||||
<ul class="oh-dropdown__items">
|
||||
<li class="oh-dropdown__item" role="button">
|
||||
<a
|
||||
class="oh-dropdown__link"
|
||||
hx-get="{% url 'load-faqs' %}"
|
||||
hx-target="#objectCreateModalTarget"
|
||||
data-target="#objectCreateModal"
|
||||
data-toggle="oh-modal-toggle"
|
||||
>
|
||||
{% trans "Load Faqs" %}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="oh-main__titlebar oh-main__titlebar--right">
|
||||
<form
|
||||
method="post"
|
||||
@@ -66,7 +99,7 @@
|
||||
</form>
|
||||
{% if perms.helpdesk.add_faqcategory %}
|
||||
<div class="oh-main__titlebar-button-container">
|
||||
<div class="oh-btn-group ml-2">
|
||||
<div class="oh-btn-group m-0">
|
||||
<div class="oh-dropdown" x-data="{open: false}">
|
||||
<button
|
||||
class="oh-btn oh-btn--secondary oh-btn--shadow"
|
||||
|
||||
@@ -1,62 +1,92 @@
|
||||
{% load i18n static %}
|
||||
{% include 'filter_tags.html' %}
|
||||
{% load i18n static %} {% include 'filter_tags.html' %}
|
||||
<div class="oh-card mb-4">
|
||||
<div class="oh-faq">
|
||||
<ul class="oh-faq__items">
|
||||
{% for faq in faqs %}
|
||||
<li class="oh-faq__item fade-me-out" id="faqItem{{faq.id}}">
|
||||
<div class="oh-faq__item-header icon-inner" onclick="show_answer(this)">
|
||||
<div class="oh-faq__item-header__left icon-inner">
|
||||
<span class="oh-faq__item-title icon-inner"> {{faq.question}} </span>
|
||||
<ul class="oh-faq__tags">
|
||||
{% for tag in faq.tags.all %}
|
||||
<li class="oh-faq__tag text-light" style="background:{{tag.color}};">{{tag|capfirst}}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
<div class="oh-faq__item-header__right">
|
||||
{% if perms.helpdesk.change_faq %}
|
||||
<button class="oh-btn oh-btn--sq oh-btn--transparent" title="{% trans 'Edit' %}"
|
||||
data-toggle="oh-modal-toggle" data-target="#objectCreateModal"
|
||||
hx-get="{% url 'faq-update' faq.id %}" hx-target="#objectCreateModalTarget"
|
||||
onclick='event.stopPropagation()'>
|
||||
<ion-icon name="create-outline"></ion-icon>
|
||||
</button>
|
||||
{% endif %}
|
||||
{% if perms.helpdesk.delete_faq %}
|
||||
<form hx-confirm="{% trans 'Are you sure you want to delete this FAQ?' %}"
|
||||
hx-target="#faqItem{{faq.id}}" hx-post="{% url 'faq-delete' faq.id %}" class="w-50"
|
||||
hx-on:click="event.stopPropagation();"
|
||||
hx-on-htmx-after-request="setTimeout(() => {reloadMessage(this);},100);"
|
||||
hx-swap="outerHTML swap:.5s">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="oh-btn oh-btn--sq oh-btn--danger-text oh-btn--transparent">
|
||||
<ion-icon class="me-1 md hydrated" name="trash-outline" role="img"
|
||||
aria-label="trash outline"></ion-icon>
|
||||
</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="oh-faq__item-body">{{faq.answer}}</div>
|
||||
</li>
|
||||
{% empty %}
|
||||
<div style="
|
||||
height: 70vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position:relative;
|
||||
">
|
||||
<div class="oh-404">
|
||||
<img style="display: block; width: 150px; height: 150px; margin: 10px auto"
|
||||
src="{% static 'images/ui/faq.png' %}" class="mb-4" alt="" />
|
||||
<h3 style="font-size: 20px" class="oh-404__subtitle">
|
||||
{% trans "There are no FAQs at the moment." %}
|
||||
</h3>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
<div class="oh-faq">
|
||||
<ul class="oh-faq__items">
|
||||
{% for faq in faqs %}
|
||||
<li class="oh-faq__item fade-me-out" id="faqItem{{faq.id}}">
|
||||
<div
|
||||
class="oh-faq__item-header icon-inner"
|
||||
onclick="show_answer(this)"
|
||||
>
|
||||
<div class="oh-faq__item-header__left icon-inner">
|
||||
<span class="oh-faq__item-title icon-inner">
|
||||
{{faq.question}}
|
||||
</span>
|
||||
<ul class="oh-faq__tags">
|
||||
{% for tag in faq.tags.all %}
|
||||
<li
|
||||
class="oh-faq__tag text-light"
|
||||
style="background:{{tag.color}};"
|
||||
>
|
||||
{{tag|capfirst}}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
<div class="oh-faq__item-header__right">
|
||||
{% if perms.helpdesk.change_faq %}
|
||||
<button
|
||||
class="oh-btn oh-btn--sq oh-btn--transparent"
|
||||
title="{% trans 'Edit' %}"
|
||||
data-toggle="oh-modal-toggle"
|
||||
data-target="#objectCreateModal"
|
||||
hx-get="{% url 'faq-update' faq.id %}"
|
||||
hx-target="#objectCreateModalTarget"
|
||||
onclick="event.stopPropagation()"
|
||||
>
|
||||
<ion-icon name="create-outline"></ion-icon>
|
||||
</button>
|
||||
{% endif %}
|
||||
{% if perms.helpdesk.delete_faq %}
|
||||
<form
|
||||
hx-confirm="{% trans 'Are you sure you want to delete this FAQ?' %}"
|
||||
hx-target="#faqItem{{faq.id}}"
|
||||
hx-post="{% url 'faq-delete' faq.id %}"
|
||||
class="w-50"
|
||||
hx-on:click="event.stopPropagation();"
|
||||
hx-on-htmx-after-request="setTimeout(() => {reloadMessage(this);},100);"
|
||||
hx-swap="outerHTML swap:.5s"
|
||||
>
|
||||
{% csrf_token %}
|
||||
<button
|
||||
type="submit"
|
||||
class="oh-btn oh-btn--sq oh-btn--danger-text oh-btn--transparent"
|
||||
>
|
||||
<ion-icon
|
||||
class="me-1 md hydrated"
|
||||
name="trash-outline"
|
||||
role="img"
|
||||
aria-label="trash outline"
|
||||
></ion-icon>
|
||||
</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="oh-faq__item-body">{{faq.answer}}</div>
|
||||
</li>
|
||||
{% empty %}
|
||||
<div
|
||||
style="
|
||||
height: 70vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
"
|
||||
>
|
||||
<div class="oh-404">
|
||||
<img
|
||||
src="{% static 'images/ui/faq.png' %}"
|
||||
class="mb-4 oh-404__image"
|
||||
alt=""
|
||||
/>
|
||||
<h3 style="font-size: 20px" class="oh-404__subtitle">
|
||||
{% trans "There are no FAQs at the moment." %}
|
||||
</h3>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,75 +1,82 @@
|
||||
{% extends 'index.html' %} {% block content %} {% load static %} {% load i18n %}
|
||||
<div id="faqContainer">
|
||||
{% include 'helpdesk/faq/faq_nav.html'%}
|
||||
<div class="oh-wrapper">
|
||||
<div id="faqList">{% include "helpdesk/faq/faq_list.html" %}</div>
|
||||
</div>
|
||||
|
||||
{% include 'helpdesk/faq/faq_nav.html'%}
|
||||
<div class="oh-wrapper">
|
||||
{% if faqs %}
|
||||
<div id="faqList">
|
||||
{% include "helpdesk/faq/faq_list.html" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div
|
||||
class="oh-modal"
|
||||
id="faqCreate"
|
||||
role="dialog"
|
||||
aria-labelledby="faqCreate"
|
||||
aria-hidden="true"
|
||||
></div>
|
||||
|
||||
<div class="oh-modal" id="faqCreate" role="dialog" aria-labelledby="faqCreate" aria-hidden="true"></div>
|
||||
<div id="addTagTargetModal">
|
||||
<div id="addTagTarget"></div>
|
||||
</div>
|
||||
|
||||
<div id="addTagTargetModal">
|
||||
<div id="addTagTarget">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="oh-modal" id="addTagModal" role="dialog" aria-labelledby="editDialogModal" aria-hidden="true"
|
||||
style="z-index: 1100;">
|
||||
<div class="oh-modal__dialog">
|
||||
<div class="oh-modal__dialog-header">
|
||||
<h2 class="oh-modal__dialog-title" id="editTitle">
|
||||
{% trans "Create Tag" %}
|
||||
</h2>
|
||||
<button class="oh-modal__close--custom"
|
||||
onclick="$(this).parents().closest('.oh-modal--show').toggleClass('oh-modal--show')" aria-label="Close">
|
||||
<ion-icon name="close-outline"></ion-icon>
|
||||
</button>
|
||||
</div>
|
||||
<div class="oh-modal__dialog-body" id="editTarget">
|
||||
<form {% comment %} hx-post="{% url 'ticket-create-tag' %}" hx-target="#addTagTarget" method="post"
|
||||
hx-encoding="multipart/form-data" {% endcomment %} id="addTagForm">
|
||||
{% csrf_token %}
|
||||
{{create_tag_f.as_p}}
|
||||
{% comment %} <button type="submit" class="oh-btn oh-btn--secondary mt-2 mr-0 oh-btn--w-100-resp">
|
||||
{% trans "Save" %}
|
||||
</button> {% endcomment %}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="oh-modal"
|
||||
id="addTagModal"
|
||||
role="dialog"
|
||||
aria-labelledby="editDialogModal"
|
||||
aria-hidden="true"
|
||||
style="z-index: 1100"
|
||||
>
|
||||
<div class="oh-modal__dialog">
|
||||
<div class="oh-modal__dialog-header">
|
||||
<h2 class="oh-modal__dialog-title" id="editTitle">
|
||||
{% trans "Create Tag" %}
|
||||
</h2>
|
||||
<button
|
||||
class="oh-modal__close--custom"
|
||||
onclick="$(this).parents().closest('.oh-modal--show').toggleClass('oh-modal--show')"
|
||||
aria-label="Close"
|
||||
>
|
||||
<ion-icon name="close-outline"></ion-icon>
|
||||
</button>
|
||||
</div>
|
||||
<div class="oh-modal__dialog-body" id="editTarget">
|
||||
<form id="addTagForm">
|
||||
{% csrf_token %} {{create_tag_f.as_p}}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function updateTag(event) {
|
||||
const selectedValues = Array.from(event.selectedOptions).map(option => option.value);
|
||||
if (selectedValues.includes('create_new_tag')) {
|
||||
$("#addTagModal").addClass("oh-modal--show");
|
||||
}
|
||||
}
|
||||
function updateTag(event) {
|
||||
const selectedValues = Array.from(event.selectedOptions).map(
|
||||
(option) => option.value
|
||||
);
|
||||
if (selectedValues.includes("create_new_tag")) {
|
||||
$("#addTagModal").addClass("oh-modal--show");
|
||||
}
|
||||
}
|
||||
|
||||
$("#addTagForm").on('submit', function () {
|
||||
event.preventDefault();
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: '/helpdesk/ticket-create-tag',
|
||||
data: $(this).serialize(),
|
||||
success: function (response) {
|
||||
var newOption = $("<option selected></option>")
|
||||
.val(response.tag_id)
|
||||
.text(response.title);
|
||||
$("#addTagForm").on("submit", function () {
|
||||
event.preventDefault();
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/helpdesk/ticket-create-tag",
|
||||
data: $(this).serialize(),
|
||||
success: function (response) {
|
||||
var newOption = $("<option selected></option>")
|
||||
.val(response.tag_id)
|
||||
.text(response.title);
|
||||
|
||||
$("#id_tags option[value='create_new_tag']").before(newOption);
|
||||
$("#id_tags option[value='create_new_tag']").prop("selected", false);
|
||||
$("#addTagModal").removeClass("oh-modal--show");
|
||||
$('#addTagForm').find('input[name="title"]').val('');
|
||||
|
||||
},
|
||||
})
|
||||
|
||||
})
|
||||
$("#id_tags option[value='create_new_tag']").before(newOption);
|
||||
$("#id_tags option[value='create_new_tag']").prop(
|
||||
"selected",
|
||||
false
|
||||
);
|
||||
$("#addTagModal").removeClass("oh-modal--show");
|
||||
$("#addTagForm").find('input[name="title"]').val("");
|
||||
},
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -4,7 +4,20 @@
|
||||
{% include 'helpdesk/faq/faq_category_nav.html'%}
|
||||
<div class="oh-wrapper">
|
||||
<div id="faqCategoryList">
|
||||
{% include "helpdesk/faq/faq_category_list.html" %}
|
||||
{% if faq_categories %}
|
||||
{% include "helpdesk/faq/faq_category_list.html" %}
|
||||
{% else %}
|
||||
<div class="oh-404">
|
||||
<img
|
||||
src="{% static 'images/ui/faq.png' %}"
|
||||
class="mb-4 oh-404__image"
|
||||
alt=""
|
||||
/>
|
||||
<h3 style="font-size: 20px" class="oh-404__subtitle">
|
||||
{% trans "There are no FAQs at the moment." %}
|
||||
</h3>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
111
helpdesk/templates/helpdesk/faq/load_faq.html
Normal file
111
helpdesk/templates/helpdesk/faq/load_faq.html
Normal file
@@ -0,0 +1,111 @@
|
||||
{% load static i18n %}
|
||||
<div class="oh-modal__dialog-header">
|
||||
<span class="oh-modal__dialog-title">{% trans "Load FAQs" %}</span>
|
||||
<button class="oh-modal__close" aria-label="Close">
|
||||
<ion-icon name="close-outline"></ion-icon>
|
||||
</button>
|
||||
</div>
|
||||
<div class="oh-modal__dialog-body">
|
||||
<div class="oh-card">
|
||||
<form hx-post="{{request.path}}" hx-target="#objectCreateModalTarget">
|
||||
<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>
|
||||
{% csrf_token %}
|
||||
{% for cat_id, category in catagories.items %}
|
||||
<div class="oh-accordion">
|
||||
<div class="oh-accordion-header">{{category}}</div>
|
||||
<div
|
||||
class="oh-accordion-body"
|
||||
style="
|
||||
max-height: 500px; overflow-y: auto;
|
||||
"
|
||||
>
|
||||
<span class="d-flex flex-row-reverse mb-2 me-3">
|
||||
<input
|
||||
type="checkbox"
|
||||
title="{% trans 'Select All' %}"
|
||||
class="custom-radio-checkmark my-2 selectAll"
|
||||
/>
|
||||
</span>
|
||||
<div
|
||||
class="oh-layout--grid-3 faqs-list"
|
||||
style="
|
||||
grid-template-columns: repeat(auto-fill, minmax(48%, 1fr));
|
||||
"
|
||||
>
|
||||
{% for faq in faqs %}
|
||||
{% if faq.fields.category == cat_id %}
|
||||
<div class="oh-card rounded">
|
||||
<div class="oh-kanban-card__details">
|
||||
<div class="d-flex-justify-between mb-2">
|
||||
<span class="oh-kanban-card__title"
|
||||
>{{faq.fields.question}}</span
|
||||
>
|
||||
<span>
|
||||
<input
|
||||
name="{{faq.pk}}"
|
||||
type="checkbox"
|
||||
class="custom-radio-checkmark"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="oh-kanban-card__subtitle truncated-text"
|
||||
style="
|
||||
height: 70px;
|
||||
white-space: wrap;
|
||||
"
|
||||
>
|
||||
{{faq.fields.answer}}
|
||||
</div>
|
||||
<ul class="oh-faq__tags m-0 flex-wrap">
|
||||
{% for tag in faq.tags %}
|
||||
<li class="oh-faq__tag {% cycle 'bg-primary' 'bg-danger' 'bg-warning' %}">
|
||||
<span class="oh-faq__tag-text text-light">{{tag}}</span>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
<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"
|
||||
>
|
||||
{% trans "Add" %}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</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>
|
||||
@@ -115,7 +115,7 @@
|
||||
</div>
|
||||
<div class = "oh-modal__button-container text-center mt-3" onclick="event.stopPropagation()">
|
||||
<div class="oh-btn-group" style="border:none">
|
||||
{% if ticket|calim_request_exists:request.user.employee_get or request.user.employee_get in ticket.assigned_to.all %}
|
||||
{% if ticket|claim_request_exists:request.user.employee_get or request.user.employee_get in ticket.assigned_to.all %}
|
||||
<a
|
||||
href="#"
|
||||
class="oh-btn oh-btn--info w-100 oh-btn--disabled"
|
||||
|
||||
@@ -6,8 +6,8 @@ from helpdesk.models import ClaimRequest, DepartmentManager
|
||||
register = template.Library()
|
||||
|
||||
|
||||
@register.filter(name="calim_request_exists")
|
||||
def calim_request_exists(ticket, employee):
|
||||
@register.filter(name="claim_request_exists")
|
||||
def claim_request_exists(ticket, employee):
|
||||
return ClaimRequest.objects.filter(ticket_id=ticket, employee_id=employee).exists()
|
||||
|
||||
|
||||
|
||||
@@ -153,4 +153,5 @@ urlpatterns = [
|
||||
views.delete_ticket_document,
|
||||
name="delete-ticket-document",
|
||||
),
|
||||
path("load-faqs/", views.load_faqs, name="load-faqs"),
|
||||
]
|
||||
|
||||
@@ -6,7 +6,9 @@ from distutils.util import strtobool
|
||||
from operator import itemgetter
|
||||
from urllib.parse import parse_qs
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib import messages
|
||||
from django.core import serializers
|
||||
from django.db.models import ProtectedError
|
||||
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
|
||||
from django.shortcuts import redirect, render
|
||||
@@ -203,6 +205,10 @@ def faq_view(request, obj_id, **kwargs):
|
||||
"""
|
||||
|
||||
faqs = FAQ.objects.filter(category=obj_id)
|
||||
faq_category = FAQCategory.objects.filter(id=obj_id)
|
||||
if not faq_category:
|
||||
messages.info(request, _("No FAQ found for the given category."))
|
||||
return redirect(faq_category_view)
|
||||
context = {
|
||||
"faqs": faqs,
|
||||
"f": FAQFilter(request.GET),
|
||||
@@ -1691,3 +1697,116 @@ def get_department_employees(request):
|
||||
context = {"employees": employees}
|
||||
employee_html = render_to_string("employee/employees_select.html", context)
|
||||
return HttpResponse(employee_html)
|
||||
|
||||
|
||||
@login_required
|
||||
def load_faqs(request):
|
||||
base_dir = settings.BASE_DIR
|
||||
faq_file = os.path.join(base_dir, "load_data", "faq.json")
|
||||
faq_category_file = os.path.join(base_dir, "load_data", "faq_category.json")
|
||||
tags_file = os.path.join(base_dir, "load_data", "tags.json")
|
||||
|
||||
with open(faq_category_file, "r") as cats:
|
||||
faq_category_raw = json.load(cats)
|
||||
|
||||
with open(tags_file, "r") as t:
|
||||
tags_raw = json.load(t)
|
||||
|
||||
with open(faq_file, "r") as faqs:
|
||||
faq_raw = json.load(faqs)
|
||||
|
||||
category_lookup = {item["pk"]: item["fields"]["title"] for item in faq_category_raw}
|
||||
|
||||
tag_lookup = {item["pk"]: item["fields"]["title"] for item in tags_raw}
|
||||
|
||||
if request.method == "POST":
|
||||
selected_ids = [int(k) for k in request.POST.keys() if k.isdigit()]
|
||||
selected_faqs = [a for a in faq_raw if a["pk"] in selected_ids]
|
||||
|
||||
category_needed = [
|
||||
faq["fields"].get("category")
|
||||
for faq in selected_faqs
|
||||
if faq["fields"].get("category")
|
||||
]
|
||||
|
||||
tags_needed_list = [
|
||||
faq["fields"].get("tags")
|
||||
for faq in selected_faqs
|
||||
if faq["fields"].get("tags")
|
||||
]
|
||||
tags_needed = [item for item_list in tags_needed_list for item in item_list]
|
||||
|
||||
for category_json in faq_category_raw:
|
||||
if category_json["pk"] in category_needed:
|
||||
category_data = list(
|
||||
serializers.deserialize("json", json.dumps([category_json]))
|
||||
)[0].object
|
||||
existing = FAQCategory.objects.filter(title=category_data.title).first()
|
||||
if not existing:
|
||||
category_data.pk = None
|
||||
category_data.save()
|
||||
|
||||
for tag_json in tags_raw:
|
||||
if tag_json["pk"] in tags_needed:
|
||||
tag_data = list(
|
||||
serializers.deserialize("json", json.dumps([tag_json]))
|
||||
)[0].object
|
||||
existing = Tags.objects.filter(title=tag_data.title).first()
|
||||
if not existing:
|
||||
tag_data.pk = None
|
||||
tag_data.save()
|
||||
|
||||
for faq_json in selected_faqs:
|
||||
deserialized = list(
|
||||
serializers.deserialize("json", json.dumps([faq_json]))
|
||||
)[0]
|
||||
faq_obj = deserialized.object
|
||||
|
||||
category_pk = faq_json["fields"].get("category")
|
||||
tag_pk = faq_json["fields"].get("tags")
|
||||
category_title = category_lookup.get(category_pk)
|
||||
tags_title = [tag_lookup.get(pk, "") for pk in tag_pk]
|
||||
category = FAQCategory.objects.filter(title=category_title).first()
|
||||
tags = Tags.objects.filter(title__in=tags_title)
|
||||
faq_obj.category = category
|
||||
|
||||
if not FAQ.objects.filter(question=faq_obj.question).exists():
|
||||
faq_obj.pk = None
|
||||
faq_obj.save()
|
||||
faq_obj.tags.set(tags)
|
||||
|
||||
messages.success(
|
||||
request, f"Automation '{faq_obj.question}' created successfully."
|
||||
)
|
||||
else:
|
||||
messages.warning(
|
||||
request, f"Automation '{faq_obj.question}' already exists."
|
||||
)
|
||||
|
||||
script = """
|
||||
<script>
|
||||
$('.oh-modal--show').removeClass('oh-modal--show');
|
||||
$('#reloadMessagesButton').click();
|
||||
$('.filterButton').click();
|
||||
</script>
|
||||
"""
|
||||
return HttpResponse(script)
|
||||
|
||||
processed_faqs = []
|
||||
for faq in faq_raw:
|
||||
processed = faq.copy()
|
||||
|
||||
category_pk = faq["fields"].get("category")
|
||||
tag_pk = faq["fields"].get("tags")
|
||||
processed["tags"] = [tag_lookup.get(pk, "") for pk in tag_pk]
|
||||
processed["category"] = category_lookup.get(category_pk, "")
|
||||
processed_faqs.append(processed)
|
||||
|
||||
return render(
|
||||
request,
|
||||
"helpdesk/faq/load_faq.html",
|
||||
{
|
||||
"faqs": processed_faqs,
|
||||
"catagories": category_lookup,
|
||||
},
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user