[ADD] DASHBOARD: Quick action buttons in the main dashboard

This commit is contained in:
Horilla
2024-01-22 19:16:08 +05:30
parent 2e2c1ce83c
commit c113c013c4
3 changed files with 505 additions and 10 deletions

View File

@@ -41,6 +41,22 @@
top: 25px;
right: 15px;
}
.container-heading {
font-size: 18px;
font-weight: bold;
padding:10px;
}
.oh-kanban-card__title {
display: block;
margin-bottom: 10px;
padding: 10px;
border:1px solid hsl(150deg 100% 15% / 52%);
border-radius: 18px;
margin-right:10px;
background-color:hsl(138.46deg 100% 74.19% / 33%);
}
</style>
<main>
<div class="oh-wrapper">
@@ -656,7 +672,7 @@
</div>
</div>
<div class="oh-dashboard__right col-12 col-sm-12 col-md-12 col-lg-3">
<div class="oh-dashboard__events">
<div class="oh-dashboard__events mb-3">
<div
class="oh-dashbaord__events-reel w-100"
id="birthdayContainer"
@@ -664,18 +680,143 @@
<ul class="oh-dashboard__events-nav" id="birthdayDots">
</ul>
</div>
<div
class="oh-card-dashboard oh-card-dashboard--no-scale oh-card-dashboard--transparent mb-3"
class="oh-card-dashboard oh-card-dashboard--no-scale oh-card-dashboard--transparent mb-3"
>
<div
class="oh-card-dashboard__header oh-card-dashboard__header--divider"
>
<div
class="oh-card-dashboard__header oh-card-dashboard__header--divider"
>
<span class="oh-card-dashboard__title">{% trans "On Leave" %}</span>
</div>
<div class="oh-card-dashboard__body">
<ul class="oh-card-dashboard__user-list" id="leaveEmployee"></ul>
</div>
<span class="oh-card-dashboard__title">{% trans "On Leave" %}</span>
</div>
<div class="oh-card-dashboard__body">
<ul class="oh-card-dashboard__user-list" id="leaveEmployee"></ul>
</div>
</div>
<div class="oh-card-dashboard oh-card-dashboard--no-scale oh-card-dashboard--transparent mb-3 mt-2">
<div class="oh-card-dashboard__title mt-4 mb-3">{% trans "Quick Actions" %}</div> <hr>
<div class="oh-card-dashboard__body">
<div class="oh-sticky-table" style="height:400px; border:none;">
<div class="oh-sticky-table__table oh-table--sortable">
<div class="oh-sticky-table__tbody">
<div class="oh-sticky-table__tr" draggable="true">
<div class="oh-kanban-card__title">
<a class="oh-profile oh-profile--md" data-toggle="oh-modal-toggle"
data-target="#newAttendanceRequest"
hx-get="{% url 'request-new-attendance' %}"
hx-target="#newAttendanceRequestModalBody">
<div class="oh-profile__avatar mr-1">
<img src="https://ui-avatars.com/api/?name=A R&background=random" class="oh-profile__image" />
</div>
<span class="oh-profile__name oh-text--dark">
{% trans "Attendance Request" %}
</span>
</a>
</div>
</div>
<div class="oh-sticky-table__tr" draggable="true">
<div class="oh-kanban-card__title">
<a class="oh-profile oh-profile--md" data-toggle="oh-modal-toggle"
data-target="#requestCreateModal"
hx-get="{% url 'leave-request-create' %}"
hx-target="#requestCreateFormModal">
<div class="oh-profile__avatar mr-1">
<img src="https://ui-avatars.com/api/?name=L R&background=random" class="oh-profile__image" />
</div>
<span class="oh-profile__name oh-text--dark">
{% trans "Leave Request" %}
</span>
</a>
</div>
</div>
<div class="oh-sticky-table__tr" draggable="true">
<div class="oh-kanban-card__title">
<a class="oh-profile oh-profile--md" data-toggle="oh-modal-toggle"
data-target="#shiftRequestModal"
hx-get="{% url 'shift-request' %}?emp_id={{request.user.employee_get.id}}"
hx-target="#shiftRequestTargetModal">
<div class="oh-profile__avatar mr-1">
<img src="https://ui-avatars.com/api/?name=S R&background=random" class="oh-profile__image" />
</div>
<span class="oh-profile__name oh-text--dark">
{% trans "Shift Request" %}
</span>
</a>
</div>
</div>
<div class="oh-sticky-table__tr" draggable="true">
<div class="oh-kanban-card__title">
<a class="oh-profile oh-profile--md" data-toggle='oh-modal-toggle'
data-target='#workTypeRequestModal'
hx-get="{% url 'work-type-request' %}"
hx-target='#formBody'>
<div class="oh-profile__avatar mr-1">
<img src="https://ui-avatars.com/api/?name=W R&background=random" class="oh-profile__image" />
</div>
<span class="oh-profile__name oh-text--dark">
{% trans "Worktype Request" %}
</span>
</a>
</div>
</div>
<div class="oh-sticky-table__tr" draggable="true">
<div class="oh-kanban-card__title">
<a class="oh-profile oh-profile--md" hx-get="{% url 'create-reimbursement' %}" hx-target="#reimbursementModalBody" data-toggle="oh-modal-toggle" data-target="#reimbursementModal">
<div class="oh-profile__avatar mr-1">
<img src="https://ui-avatars.com/api/?name=R R&background=random" class="oh-profile__image" />
</div>
<span class="oh-profile__name oh-text--dark">
{% trans "Reimbursement Request" %}
</span>
</a>
</div>
</div>
<div class="oh-sticky-table__tr" draggable="true">
<div class="oh-kanban-card__title">
<a class="oh-profile oh-profile--md" data-toggle="oh-modal-toggle"
data-target="#asset-request-allocation-modal"
hx-get="{%url 'asset-request-creation'%}"
hx-target="#asset-request-allocation-modal-target">
<div class="oh-profile__avatar mr-1">
<img src="https://ui-avatars.com/api/?name=A R&background=random" class="oh-profile__image" />
</div>
<span class="oh-profile__name oh-text--dark">
{% trans "Asset Request" %}
</span>
</a>
</div>
</div>
<div class="oh-sticky-table__tr" draggable="true">
<div class="oh-kanban-card__title">
<a class="oh-profile oh-profile--md" data-toggle="oh-modal-toggle"
data-target="#createModal1"
hx-get="{% url 'ticket-create' %}"
hx-target="#createTarget">
<div class="oh-profile__avatar mr-1">
<img src="https://ui-avatars.com/api/?name=T C&background=random" class="oh-profile__image" />
</div>
<span class="oh-profile__name oh-text--dark">
{% trans "Ticket Creation" %}
</span>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% if perms.leave.view_leaverequest or request.user|is_reportingmanager%}
<div
class="oh-card-dashboard oh-card-dashboard--no-scale oh-card-dashboard--transparent"
@@ -820,6 +961,8 @@
</div>
</div>
{% include "quick_access.html" %}
</main>

325
templates/quick_access.html Normal file
View File

@@ -0,0 +1,325 @@
{% load static %}
{% load i18n %}
<!-- ******************** Leave modal ******************** -->
<div
class="oh-modal"
id="requestCreateModal"
role="dialog"
aria-labelledby="requestCreateModal"
aria-hidden="true"
>
<div class="oh-modal__dialog" id="requestCreateFormModal">
</div>
</div>
<div
class="oh-modal"
id="tableTimeOff"
role="dialog"
aria-labelledby="tableTimeOffModal"
aria-hidden="true"
>
<div
class="oh-modal__dialog oh-modal__dialog--timeoff oh-modal__dialog-relative oh-timeoff-modal"
>
<div class="oh-modal__dialog-header">
<button class="oh-modal__close" aria-label="Close">
<ion-icon name="close-outline"></ion-icon>
</button>
</div>
<div id="userRequestView"></div>
</div>
</div>
<!-- ******************** Attendance modal ******************** -->
<div
class="oh-modal"
id="newAttendanceRequest"
role="dialog"
aria-labelledby="newAttendanceRequest"
aria-hidden="true"
>
<div class="oh-modal__dialog">
<div class="oh-modal__dialog-header">
<h2 class="oh-modal__dialog-title" id="addEmployeeModalLabel">
{% trans "New Attendances Request" %}
</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="newAttendanceRequestModalBody"
></div>
</div>
</div>
<!-- ******************** Shift modal ******************** -->
<div class="oh-modal" id="shiftRequestModal" role="dialog" aria-labelledby="shiftRequestModal" aria-hidden="true">
<div class="oh-modal__dialog" id="shiftRequestTargetModal"></div>
</div>
<!-- ******************** Worktype modal ******************** -->
<div
class="oh-modal"
id="workTypeRequestModal"
role="dialog"
aria-labelledby="workTypeRequestModal"
aria-hidden="true"
>
<div class="oh-modal__dialog">
<div class="oh-modal__dialog-header">
<h5 class="oh-modal__dialog-title" id="workTypeRequestModalLabel"
>{% trans "Work Type Request" %}</span
>
<button class="oh-modal__close" aria-label="Close" >
<ion-icon name="close-outline"></ion-icon>
</button>
</div>
<div class="oh-modal__dialog-body" id='formBody'>
</div>
</div>
</div>
</div>
<!-- ******************** Reimbursement modal ******************** -->
<div class="oh-modal" id="reimbursementModal" role="dialog" aria-hidden="true">
<div class="oh-modal__dialog" style="max-width: 550px">
<div class="oh-modal__dialog-header">
<button type="button" class="oh-modal__close" aria-label="Close"><ion-icon name="close-outline"></ion-icon></button>
</div>
<div class="oh-modal__dialog-body" id="reimbursementModalBody"></div>
</div>
</div>
<!-- ******************** Asset modal ******************** -->
<div
class="oh-modal"
id="asset-request-allocation-modal"
role="dialog"
aria-labelledby="AssetRequestModal"
aria-hidden="true"
>
<div class="oh-modal__dialog" style="max-width: 550px">
<div class="oh-modal__dialog-header">
<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"
id="asset-request-allocation-modal-target"
></div>
</div>
</div>
<!-- ******************** Ticket modal ******************** -->
<div
class="oh-modal"
id="createModal1"
role="dialog"
aria-labelledby="createDialogModal"
aria-hidden="true"
>
<div class="oh-modal__dialog">
<div class="oh-modal__dialog-header">
<h2 class="oh-modal__dialog-title" id="createTitle">
{% trans "Create Ticket" %}
</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="createTarget"></div>
</div>
</div>
<script>
// ==================== Leave request ====================
$(document).on('htmx:load','#userLeaves', function () {
// Create a new script element
var scriptElement = document.createElement("script");
// Set the source URL of the script file to be loaded
scriptElement.src = "{% static 'build/js/web.frontend.min.js' %}";
// Append the script element to the head of the HTML document
document.head.appendChild(scriptElement);
});
$(document).on('htmx:load', '#requestForm', function () {
{% include 'select2.js' %}
$('#leaveType #id_leave_type_id').select2();
$('#employee #id_employee_id').select2();
$('#startDate #id_start_date_breakdown').select2();
$('#endDate #id_end_date_breakdown').select2();
});
function typeChange(selectElement) {
var selectedLeavetype =selectElement.val()
let parentForm = selectElement.parents().closest("form")
var employeeId = parentForm.find('[name = employee_id]').val()
$.ajax({
type: "post",
url: "{% url 'employee-leave-details' %}",
data: {
csrfmiddlewaretoken: getCookie("csrftoken"),
"leave_type":selectedLeavetype,
"employee_id":employeeId,
},
success: function (response) {
// Assuming parentForm is a reference to the form containing the element to update
var messageDiv = parentForm.find(".leave-message");
// Check if the messageDiv already exists, if not create it
if (!messageDiv.length) {
messageDiv = $("<div class='leave-message'></div>");
parentForm.prepend(messageDiv);
}
// Checking leave type is selected in the form or not
if (response.leave_count === ''){
messageDiv.hide()
}
else if (response.leave_count === 0.0){
messageDiv.show()
messageDiv.text("Available Leaves : " + response.leave_count);
messageDiv.css({
'background-color': 'rgb(229 79 56 / 17%)',
'border': '2px solid hsl(8,77%,56%)',
'border-radius': '18px',
'padding': '10px',
'font-weight': 'bold',
'margin-bottom': '15px',
'width': '35%'
});
}
else{
messageDiv.show()
// Set the message content and apply styling
messageDiv.text("Available Leaves : " + response.leave_count);
messageDiv.css({
'background-color': '#dff0d8',
'border': '2px solid #3c763d',
'border-radius': '18px',
'padding': '10px',
'font-weight': 'bold',
'margin-bottom': '15px',
'width': '35%'
});
}
}
});
}
// ==================== Attendance request ====================
function shiftChange(selectElement) {
var shiftId =selectElement.val()
let parentForm = selectElement.parents().closest("form")
var attendanceDate = parentForm.find("[name=attendance_date]").first().val()
$.ajax({
type: "post",
url: "{% url 'update-shift-details' %}",
data: {
csrfmiddlewaretoken: getCookie("csrftoken"),
"shift_id":shiftId,
"attendance_date":attendanceDate
},
success: function (response) {
parentForm.find("[name=attendance_clock_in]").val(response.shift_start_time)
parentForm.find("[name=attendance_clock_out]").val(response.shift_end_time)
parentForm.find("[name=attendance_worked_hour]").val(response.worked_hour)
parentForm.find("[name=minimum_hour]").val(response.minimum_hour)
parentForm.find("[name=attendance_clock_out_date]").val(response.checkout_date)
parentForm.find("[name=attendance_clock_in_date]").val(response.checkin_date)
if (parentForm.find("[name=attendance_date]").val().length == 0) {
parentForm.find("[name=attendance_date]").val(response.checkin_date)
}
}
});
}
function dateChange(selectElement) {
var selectedDate =selectElement.val()
let parentForm = selectElement.parents().closest("form")
var shiftId = parentForm.find("[name=shift_id]").val()
$.ajax({
type: "post",
url: "{% url 'update-date-details' %}",
data: {
csrfmiddlewaretoken: getCookie("csrftoken"),
"attendance_date":selectedDate,
"shift_id":shiftId
},
success: function (response) {
parentForm.find("[name=minimum_hour]").val(response.minimum_hour)
}
});
}
// ==================== Reimbursement request ====================
function toggleReimbursmentType(element) {
if (element.val() == 'reimbursement') {
$('#reimbursementModalBody [name=attachment]').parent().show()
$('#reimbursementModalBody [name=attachment]').attr("required",true)
$('#reimbursementModalBody [name=leave_type_id]').parent().hide().attr("required",false)
$('#reimbursementModalBody [name=cfd_to_encash]').parent().hide().attr("required",false)
$('#reimbursementModalBody [name=ad_to_encash]').parent().hide().attr("required",false)
$('#reimbursementModalBody [name=amount]').parent().show().attr("required",true)
$('#reimbursementModalBody #availableTable').hide().attr("required",false)
} else if(element.val() == 'leave_encashment') {
$('#reimbursementModalBody [name=attachment]').parent().hide()
$('#reimbursementModalBody [name=attachment]').attr("required",false)
$('#reimbursementModalBody [name=leave_type_id]').parent().show().attr("required",true)
$('#reimbursementModalBody [name=cfd_to_encash]').parent().show().attr("required",true)
$('#reimbursementModalBody [name=ad_to_encash]').parent().show().attr("required",true)
$('#reimbursementModalBody [name=amount]').parent().hide().attr("required",false)
$('#reimbursementModalBody #availableTable').show().attr("required",true)
}
}
function getAssignedLeave(employeeId) {
$.ajax({
type: "get",
url: "{% url "get-assigned-leaves" %}",
data: { "employeeId": employeeId },
dataType: "json",
success: function (response) {
let rows = ""
for (let index = 0; index < response.length; index++) {
const element = response[index];
rows = rows + `<tr class="toggle-highlight"><td>${element.leave_type_id__name
}</td><td>${element.available_days}</td><td>${element.carryforward_days}</td></tr>`
}
$("#availableTableBody").html($(rows))
removeHighlight()
}
});
}
</script>

View File

@@ -82,6 +82,33 @@
<span>{% trans "Dashboard" %}</span>
</a>
</li>
{% comment %}
<li
class="oh-sidebar__menu-item"
x-data="{ isOpen: getOpenState('announcementNav') }"
>
<a
href="{%url 'announcement' %}"
onclick="window.location.href=this.href; return false;"
class="oh-sidebar__menu-link"
data-id="announcementNav"
x-on:click.prevent="isOpen = !isOpen; saveOpenState('announcementNav', isOpen)"
x-bind:class="isOpen ? 'oh-sidebar__menu-link--active' : ''"
>
<div class="oh-sidebar__menu-icon">
<img
src="{% static 'images/ui/announcement.svg' %}"
alt="Dashboard"
width="24"
height="24"
/>
</div>
<span>{% trans "Announcement" %}</span>
</a>
</li>
{% endcomment %}
{% if request.user|is_stagemanager or 'recruitment' in perms %}
<li
class="oh-sidebar__menu-item"