Abstract Model Changes (#131)
* [UPDT] BASE: Updated disciplinary action type model by adding abstract class * [UPDT] BASE: Updated abstract model class save method by fethcing request from thread local * [UPDT] LEAVE: Updated models in leave module by adding abstract class * [UPDT] LEAVE: Updated leave request model by adding abstract class * [UPDT] DASHBOARD: Floating quick action button rather than static template inside dashboard * [UPDT] Test database * [UPDT] ASSET: Updated models in asset app by adding abstract class HorillaModels * [UPDT] ASSET: Updated asset category form by adding exclude fields in class Meta * [FIX] ATTENDANCE: Attendance overtime permission wrong permission * [UPDT] Test Database
This commit is contained in:
@@ -40,9 +40,9 @@
|
||||
<a
|
||||
class=""
|
||||
data-toggle="oh-modal-toggle"
|
||||
data-target="#createModal1"
|
||||
data-target="#objectCreateModal"
|
||||
hx-get="{% url 'ticket-create' %}?status={{status}}"
|
||||
hx-target="#createTarget"
|
||||
hx-target="#objectCreateModalTarget"
|
||||
title="Add Tickets"
|
||||
>
|
||||
<ion-icon
|
||||
@@ -126,9 +126,9 @@
|
||||
"
|
||||
class="oh-dropdown__link oh-dropdown__link--secondary"
|
||||
data-toggle="oh-modal-toggle"
|
||||
data-target="#editModal"
|
||||
data-target="#objectCreateModal"
|
||||
hx-get="{% url 'ticket-update' ticket.id %}"
|
||||
hx-target="#editTarget"
|
||||
hx-target="#objectCreateModalTarget"
|
||||
onclick="event.stopPropagation()"
|
||||
>{% trans "Edit" %}</a
|
||||
>
|
||||
@@ -267,9 +267,9 @@
|
||||
<a
|
||||
class=""
|
||||
data-toggle="oh-modal-toggle"
|
||||
data-target="#createModal1"
|
||||
data-target="#objectCreateModal"
|
||||
hx-get="{% url 'ticket-create' %}?status={{status}}"
|
||||
hx-target="#createTarget"
|
||||
hx-target="#objectCreateModalTarget"
|
||||
title="Add Tickets"
|
||||
>
|
||||
<ion-icon
|
||||
@@ -354,9 +354,9 @@
|
||||
"
|
||||
class="oh-dropdown__link oh-dropdown__link--secondary"
|
||||
data-toggle="oh-modal-toggle"
|
||||
data-target="#editModal"
|
||||
data-target="#objectCreateModal"
|
||||
hx-get="{% url 'ticket-update' ticket.id %}"
|
||||
hx-target="#editTarget"
|
||||
hx-target="#objectCreateModalTarget"
|
||||
onclick="event.stopPropagation()"
|
||||
>{% trans "Edit" %}</a
|
||||
>
|
||||
@@ -510,9 +510,9 @@
|
||||
<a
|
||||
class=""
|
||||
data-toggle="oh-modal-toggle"
|
||||
data-target="#createModal1"
|
||||
data-target="#objectCreateModal"
|
||||
hx-get="{% url 'ticket-create' %}?status={{status}}"
|
||||
hx-target="#createTarget"
|
||||
hx-target="#objectCreateModalTarget"
|
||||
title="Add Tickets"
|
||||
>
|
||||
<ion-icon
|
||||
@@ -596,9 +596,9 @@
|
||||
"
|
||||
class="oh-dropdown__link oh-dropdown__link--secondary"
|
||||
data-toggle="oh-modal-toggle"
|
||||
data-target="#editModal"
|
||||
data-target="#objectCreateModal"
|
||||
hx-get="{% url 'ticket-update' ticket.id %}"
|
||||
hx-target="#editTarget"
|
||||
hx-target="#objectCreateModalTarget"
|
||||
onclick="event.stopPropagation()"
|
||||
>{% trans "Edit" %}</a
|
||||
>
|
||||
|
||||
@@ -1,204 +1,276 @@
|
||||
{% load i18n %}
|
||||
{% if form.errors %}
|
||||
<!-- form errors -->
|
||||
<div class="oh-wrapper">
|
||||
<div class="oh-alert-container">
|
||||
{% for error in form.non_field_errors %}
|
||||
<div class="oh-alert oh-alert--animated oh-alert--danger">
|
||||
{{ error }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div hidden id=cur_raised_on value= "{{form.instance.raised_on}}">{{form.instance.raised_on}}</div>
|
||||
<form hx-post="{% if ticket_id %}{% url 'ticket-update' ticket_id %}{% else %}{% url 'ticket-create' %}{% endif %}"
|
||||
hx-encoding="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
{{form.as_p}}
|
||||
</form>
|
||||
<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 %}
|
||||
</h2>
|
||||
<button type="button" class="oh-modal__close" aria-label="Close">
|
||||
<ion-icon name="close-outline"></ion-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- htmx form -->
|
||||
<div
|
||||
class="oh-modal__dialog-body"
|
||||
>
|
||||
{% if form.errors %}
|
||||
<!-- form errors -->
|
||||
<div class="oh-wrapper">
|
||||
<div class="oh-alert-container">
|
||||
{% for error in form.non_field_errors %}
|
||||
<div class="oh-alert oh-alert--animated oh-alert--danger">
|
||||
{{ error }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<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"
|
||||
>
|
||||
{% csrf_token %} {{form.as_p}}
|
||||
</form>
|
||||
</div>
|
||||
<!-- start of create tag modal. -->
|
||||
<div id="addTagModal">
|
||||
<div id="addTagTarget">
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
<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__dialog">
|
||||
<div class="oh-modal__dialog-header">
|
||||
<h2 class="oh-modal__dialog-title" id="editTitle">
|
||||
{% trans "Create Tag" %}
|
||||
</h2>
|
||||
|
||||
<button style="order: none;
|
||||
background: none;
|
||||
font-size: 1.5rem;
|
||||
opacity: 0.7;
|
||||
position: absolute;
|
||||
top: 25px;
|
||||
right: 15px;
|
||||
cursor: pointer;
|
||||
-webkit-transition: all 0.3s ease-in-out;
|
||||
transition: all 0.3s ease-in-out;"
|
||||
|
||||
aria-label="Close"
|
||||
<div class="oh-modal__dialog-header">
|
||||
<h2 class="oh-modal__dialog-title" id="editTitle">
|
||||
{% trans "Create Tag" %}
|
||||
</h2>
|
||||
|
||||
<button
|
||||
style="
|
||||
order: none;
|
||||
background: none;
|
||||
font-size: 1.5rem;
|
||||
opacity: 0.7;
|
||||
position: absolute;
|
||||
top: 25px;
|
||||
right: 15px;
|
||||
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);"
|
||||
|
||||
|
||||
>
|
||||
<ion-icon name="close-outline"></ion-icon>
|
||||
</button>
|
||||
</div>
|
||||
<div class="oh-modal__dialog-body" id="editTarget">
|
||||
|
||||
<form
|
||||
onsubmit="saveTag();event.preventDefault();"
|
||||
>
|
||||
{% 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">
|
||||
<ion-icon name="close-outline"></ion-icon>
|
||||
</button>
|
||||
</div>
|
||||
<div class="oh-modal__dialog-body" id="editTarget">
|
||||
<form onsubmit="saveTag();event.preventDefault();">
|
||||
{% csrf_token %}
|
||||
|
||||
<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;">
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
class="oh-btn oh-btn--secondary mt-2 mr-0 oh-btn--w-100-resp"
|
||||
>
|
||||
{% trans "Save" %}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
<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"
|
||||
/>
|
||||
|
||||
<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"
|
||||
/>
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
class="oh-btn oh-btn--secondary mt-2 mr-0 oh-btn--w-100-resp"
|
||||
>
|
||||
{% trans "Save" %}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end of create tag modal. -->
|
||||
<!-- start of create ticket type modal. -->
|
||||
|
||||
<div id="addTicketTypeModal">
|
||||
<div id="addTicketTypeTarget">
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
<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__dialog">
|
||||
<div class="oh-modal__dialog-header">
|
||||
<h2 class="oh-modal__dialog-title" id="editTitle">
|
||||
{% trans "Create Ticket Type" %}
|
||||
</h2>
|
||||
<button class="oh-modal__close--custom" onclick="$('#createTicketTypeModal').removeClass('oh-modal--show')" aria-label="Close">
|
||||
<ion-icon name="close-outline"></ion-icon>
|
||||
</button>
|
||||
</div>
|
||||
<div class="oh-modal__dialog-body" id="editTarget">
|
||||
|
||||
<form
|
||||
onsubmit="saveTicketType();event.preventDefault();"
|
||||
>
|
||||
{% 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-modal__dialog-header">
|
||||
<h2 class="oh-modal__dialog-title" id="editTitle">
|
||||
{% trans "Create Ticket Type" %}
|
||||
</h2>
|
||||
<button
|
||||
class="oh-modal__close--custom"
|
||||
onclick="$('#createTicketTypeModal').removeClass('oh-modal--show')"
|
||||
aria-label="Close"
|
||||
>
|
||||
<ion-icon name="close-outline"></ion-icon>
|
||||
</button>
|
||||
</div>
|
||||
<div class="oh-modal__dialog-body" id="editTarget">
|
||||
<form onsubmit="saveTicketType();event.preventDefault();">
|
||||
{% 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>
|
||||
{{ t_type_form.type }}
|
||||
<label class="oh-label">{% trans "Prefix" %}</label>
|
||||
<label class="oh-label">{% trans "Prefix" %}</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 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 "Save" %}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</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"
|
||||
>
|
||||
{% trans "Save" %}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end of create ticket type modal. -->
|
||||
|
||||
<script>
|
||||
$(document).ready( function(){
|
||||
var assigning_type = $('#id_assigning_type').val();
|
||||
if (assigning_type) {
|
||||
$(document).ready(function () {
|
||||
var assigning_type = $("#id_assigning_type").val();
|
||||
if (assigning_type) {
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: "/helpdesk/get-raised-on",
|
||||
data: {
|
||||
'assigning_type': assigning_type,
|
||||
assigning_type: assigning_type,
|
||||
},
|
||||
success: function (response) {
|
||||
var raised_on = response.raised_on;
|
||||
var cur_raised_on = $('#cur_raised_on').attr('value');
|
||||
var cur_raised_on = $("#cur_raised_on").attr("value");
|
||||
// Clear the existing options
|
||||
$('#id_raised_on').empty();
|
||||
var options = $('<option value="" >').text('---------');
|
||||
$('#id_raised_on').append(options);
|
||||
|
||||
$("#id_raised_on").empty();
|
||||
var options = $('<option value="" >').text("---------");
|
||||
$("#id_raised_on").append(options);
|
||||
|
||||
$.each(raised_on, function (id, obj) {
|
||||
// looping all raised_on
|
||||
var options = $('<option value="' + obj.id + '" ' + (obj.id == cur_raised_on ? 'selected="selected"' : '') + '>').text(obj.name);
|
||||
$('#id_raised_on').append(options);
|
||||
var options = $(
|
||||
'<option value="' +
|
||||
obj.id +
|
||||
'" ' +
|
||||
(obj.id == cur_raised_on
|
||||
? 'selected="selected"'
|
||||
: "") +
|
||||
">"
|
||||
).text(obj.name);
|
||||
$("#id_raised_on").append(options);
|
||||
});
|
||||
},
|
||||
});
|
||||
} else {
|
||||
var options = $('<option value="" selected="selected">').text('---------');
|
||||
$('#id_raised_on').append(options);
|
||||
var options = $('<option value="" selected="selected">').text(
|
||||
"---------"
|
||||
);
|
||||
$("#id_raised_on").append(options);
|
||||
}
|
||||
|
||||
$('#id_assigning_type').change(function(){
|
||||
|
||||
var assigning_type = $('#id_assigning_type').val()
|
||||
$("#id_assigning_type").change(function () {
|
||||
var assigning_type = $("#id_assigning_type").val();
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: "/helpdesk/get-raised-on",
|
||||
data:{
|
||||
'assigning_type':assigning_type,
|
||||
data: {
|
||||
assigning_type: assigning_type,
|
||||
},
|
||||
success: function (response) {
|
||||
var raised_on = response.raised_on
|
||||
var raised_on = response.raised_on;
|
||||
// Clear the existing options
|
||||
$('#id_raised_on').empty();
|
||||
var options = $(`<option value=" " selected="selected">`).text(`---------`);
|
||||
$("#id_raised_on").empty();
|
||||
var options = $(
|
||||
`<option value=" " selected="selected">`
|
||||
).text(`---------`);
|
||||
|
||||
$('#id_raised_on').append(options)
|
||||
$.each(raised_on, function (id,obj) {
|
||||
$("#id_raised_on").append(options);
|
||||
$.each(raised_on, function (id, obj) {
|
||||
// looping all raised_on
|
||||
var options = $(`<option value=" ${obj.id}">`).text(obj.name);
|
||||
$('#id_raised_on').append(options)
|
||||
});
|
||||
|
||||
var options = $(`<option value=" ${obj.id}">`).text(
|
||||
obj.name
|
||||
);
|
||||
$("#id_raised_on").append(options);
|
||||
});
|
||||
},
|
||||
});
|
||||
})
|
||||
$('#id_tags').change(function(){
|
||||
var selectedValues = $("#id_tags option:selected").map(function(){
|
||||
return $(this).val();
|
||||
}).get();
|
||||
// Check if 'create_new_tag' exists in the list
|
||||
if (selectedValues.includes('create_new_tag')) {
|
||||
});
|
||||
$("#id_tags").change(function () {
|
||||
var selectedValues = $("#id_tags option:selected")
|
||||
.map(function () {
|
||||
return $(this).val();
|
||||
})
|
||||
.get();
|
||||
// Check if 'create_new_tag' exists in the list
|
||||
if (selectedValues.includes("create_new_tag")) {
|
||||
$("#createTagModal").addClass("oh-modal--show");
|
||||
}
|
||||
})
|
||||
$('#id_ticket_type').change(function(){
|
||||
var selectedValues = $("#id_ticket_type").val()
|
||||
// Check if 'create_new_ticket_type' is selected
|
||||
if (selectedValues == 'create_new_ticket_type') {
|
||||
}
|
||||
});
|
||||
$("#id_ticket_type").change(function () {
|
||||
var selectedValues = $("#id_ticket_type").val();
|
||||
// Check if 'create_new_ticket_type' is selected
|
||||
if (selectedValues == "create_new_ticket_type") {
|
||||
$("#createTicketTypeModal").addClass("oh-modal--show");
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
</script>
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -121,9 +121,9 @@
|
||||
class="oh-btn oh-btn--light-bkg w-50"
|
||||
title="{% trans 'Edit' %}"
|
||||
data-toggle="oh-modal-toggle"
|
||||
data-target="#editModal"
|
||||
data-target="#objectCreateModal"
|
||||
hx-get="{% url 'ticket-update' ticket.id %}"
|
||||
hx-target="#editTarget"
|
||||
hx-target="#objectCreateModalTarget"
|
||||
>
|
||||
<ion-icon name="create-outline"></ion-icon>
|
||||
</button>
|
||||
@@ -417,9 +417,9 @@
|
||||
class="oh-btn oh-btn--light-bkg w-50"
|
||||
title="{% trans 'Edit' %}"
|
||||
data-toggle="oh-modal-toggle"
|
||||
data-target="#editModal"
|
||||
data-target="#objectCreateModal"
|
||||
hx-get="{% url 'ticket-update' ticket.id %}"
|
||||
hx-target="#editTarget"
|
||||
hx-target="#objectCreateModalTarget"
|
||||
>
|
||||
<ion-icon name="create-outline"></ion-icon>
|
||||
</button>
|
||||
@@ -712,9 +712,9 @@
|
||||
class="oh-btn oh-btn--light-bkg w-50"
|
||||
title="{% trans 'Edit' %}"
|
||||
data-toggle="oh-modal-toggle"
|
||||
data-target="#editModal"
|
||||
data-target="#objectCreateModal"
|
||||
hx-get="{% url 'ticket-update' ticket.id %}"
|
||||
hx-target="#editTarget"
|
||||
hx-target="#objectCreateModalTarget"
|
||||
>
|
||||
<ion-icon name="create-outline"></ion-icon>
|
||||
</button>
|
||||
|
||||
@@ -116,9 +116,9 @@
|
||||
class="oh-btn oh-btn--light-bkg p-3 w-50"
|
||||
title="{% trans 'Edit' %}"
|
||||
data-toggle="oh-modal-toggle"
|
||||
data-target="#editModal"
|
||||
data-target="#objectCreateModal"
|
||||
hx-get="{% url 'ticket-update' ticket.id %}"
|
||||
hx-target="#editTarget"
|
||||
hx-target="#objectCreateModalTarget"
|
||||
>
|
||||
<ion-icon name="create-outline"></ion-icon>
|
||||
</button>
|
||||
@@ -353,9 +353,9 @@
|
||||
class="oh-btn oh-btn--light-bkg p-3 w-100"
|
||||
title="{% trans 'Edit' %}"
|
||||
data-toggle="oh-modal-toggle"
|
||||
data-target="#editModal"
|
||||
data-target="#objectCreateModal"
|
||||
hx-get="{% url 'ticket-update' ticket.id %}"
|
||||
hx-target="#editTarget"
|
||||
hx-target="#objectCreateModalTarget"
|
||||
>
|
||||
<ion-icon name="create-outline"></ion-icon>
|
||||
</button>
|
||||
@@ -577,9 +577,9 @@
|
||||
class="oh-btn oh-btn--light-bkg p-3 w-50"
|
||||
title="{% trans 'Edit' %}"
|
||||
data-toggle="oh-modal-toggle"
|
||||
data-target="#editModal"
|
||||
data-target="#objectCreateModal"
|
||||
hx-get="{% url 'ticket-update' ticket.id %}"
|
||||
hx-target="#editTarget"
|
||||
hx-target="#objectCreateModalTarget"
|
||||
>
|
||||
<ion-icon name="create-outline"></ion-icon>
|
||||
</button>
|
||||
|
||||
@@ -85,9 +85,9 @@
|
||||
<button
|
||||
class="oh-btn oh-btn--secondary oh-btn--shadow"
|
||||
data-toggle="oh-modal-toggle"
|
||||
data-target="#createModal1"
|
||||
data-target="#objectCreateModal"
|
||||
hx-get="{% url 'ticket-create' %}"
|
||||
hx-target="#createTarget"
|
||||
hx-target="#objectCreateModalTarget"
|
||||
>
|
||||
<ion-icon
|
||||
name="add-outline"
|
||||
|
||||
Reference in New Issue
Block a user