hospital-management/templates/hr/performance_evaluation.html
2025-08-12 13:33:25 +03:00

929 lines
42 KiB
HTML

{% extends 'base.html' %}
{% load static %}
{% block title %}Performance Evaluation{% endblock %}
{% block content %}
<div id="content" class="app-content">
<div class="container">
<ul class="breadcrumb">
<li class="breadcrumb-item"><a href="{% url 'core:dashboard' %}">Dashboard</a></li>
<li class="breadcrumb-item"><a href="{% url 'hr:dashboard' %}">HR</a></li>
<li class="breadcrumb-item active">Performance Evaluation</li>
</ul>
<div class="row align-items-center mb-3">
<div class="col">
<h1 class="page-header">Performance Evaluation</h1>
<p class="text-muted">Employee performance review and evaluation system</p>
</div>
<div class="col-auto">
<div class="btn-group">
<button class="btn btn-primary" onclick="createEvaluation()">
<i class="fa fa-plus me-2"></i>New Evaluation
</button>
<button class="btn btn-outline-secondary" onclick="exportEvaluations()">
<i class="fa fa-download me-2"></i>Export
</button>
<button class="btn btn-outline-info" onclick="viewAnalytics()">
<i class="fa fa-chart-line me-2"></i>Analytics
</button>
</div>
</div>
</div>
<!-- Evaluation Overview -->
<div class="row mb-4">
<div class="col-md-3">
<div class="card bg-primary text-white">
<div class="card-body">
<div class="d-flex align-items-center">
<div class="flex-grow-1">
<h4 class="mb-0">{{ total_evaluations }}</h4>
<p class="mb-0">Total Evaluations</p>
</div>
<div class="ms-3">
<i class="fa fa-clipboard-list fa-2x"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card bg-success text-white">
<div class="card-body">
<div class="d-flex align-items-center">
<div class="flex-grow-1">
<h4 class="mb-0">{{ completed_evaluations }}</h4>
<p class="mb-0">Completed</p>
</div>
<div class="ms-3">
<i class="fa fa-check-circle fa-2x"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card bg-warning text-white">
<div class="card-body">
<div class="d-flex align-items-center">
<div class="flex-grow-1">
<h4 class="mb-0">{{ pending_evaluations }}</h4>
<p class="mb-0">Pending</p>
</div>
<div class="ms-3">
<i class="fa fa-clock fa-2x"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card bg-info text-white">
<div class="card-body">
<div class="d-flex align-items-center">
<div class="flex-grow-1">
<h4 class="mb-0">{{ average_score|floatformat:1 }}</h4>
<p class="mb-0">Average Score</p>
</div>
<div class="ms-3">
<i class="fa fa-star fa-2x"></i>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Search and Filters -->
<div class="row mb-4">
<div class="col-12">
<div class="card">
<div class="card-header">
<h4 class="card-title">Search & Filter</h4>
<div class="card-tools">
<button class="btn btn-outline-secondary btn-sm" onclick="resetFilters()">
<i class="fa fa-refresh me-1"></i>Reset
</button>
</div>
</div>
<div class="card-body">
<form id="searchForm" class="row g-3">
<div class="col-md-3">
<label class="form-label">Search Employee</label>
<input type="text" class="form-control" name="search" placeholder="Name, ID, or department..." value="{{ request.GET.search }}">
</div>
<div class="col-md-2">
<label class="form-label">Status</label>
<select class="form-select" name="status">
<option value="">All Statuses</option>
<option value="draft" {% if request.GET.status == 'draft' %}selected{% endif %}>Draft</option>
<option value="in_progress" {% if request.GET.status == 'in_progress' %}selected{% endif %}>In Progress</option>
<option value="completed" {% if request.GET.status == 'completed' %}selected{% endif %}>Completed</option>
<option value="approved" {% if request.GET.status == 'approved' %}selected{% endif %}>Approved</option>
<option value="rejected" {% if request.GET.status == 'rejected' %}selected{% endif %}>Rejected</option>
</select>
</div>
<div class="col-md-2">
<label class="form-label">Evaluation Period</label>
<select class="form-select" name="period">
<option value="">All Periods</option>
<option value="annual" {% if request.GET.period == 'annual' %}selected{% endif %}>Annual</option>
<option value="semi_annual" {% if request.GET.period == 'semi_annual' %}selected{% endif %}>Semi-Annual</option>
<option value="quarterly" {% if request.GET.period == 'quarterly' %}selected{% endif %}>Quarterly</option>
<option value="probationary" {% if request.GET.period == 'probationary' %}selected{% endif %}>Probationary</option>
</select>
</div>
<div class="col-md-2">
<label class="form-label">Department</label>
<select class="form-select" name="department">
<option value="">All Departments</option>
{% for dept in departments %}
<option value="{{ dept.id }}" {% if request.GET.department == dept.id|stringformat:"s" %}selected{% endif %}>{{ dept.name }}</option>
{% endfor %}
</select>
</div>
<div class="col-md-2">
<label class="form-label">Evaluator</label>
<select class="form-select" name="evaluator">
<option value="">All Evaluators</option>
{% for evaluator in evaluators %}
<option value="{{ evaluator.id }}" {% if request.GET.evaluator == evaluator.id|stringformat:"s" %}selected{% endif %}>{{ evaluator.get_full_name }}</option>
{% endfor %}
</select>
</div>
<div class="col-md-1">
<label class="form-label">&nbsp;</label>
<button type="submit" class="btn btn-primary form-control">
<i class="fa fa-search"></i>
</button>
</div>
</form>
</div>
</div>
</div>
</div>
<!-- Evaluation List -->
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header">
<h4 class="card-title">Performance Evaluations</h4>
<div class="card-tools">
<div class="btn-group">
<button class="btn btn-outline-primary btn-sm" onclick="bulkAction('approve')">
<i class="fa fa-check me-1"></i>Bulk Approve
</button>
<button class="btn btn-outline-warning btn-sm" onclick="bulkAction('remind')">
<i class="fa fa-bell me-1"></i>Send Reminders
</button>
<button class="btn btn-outline-info btn-sm" onclick="generateReport()">
<i class="fa fa-file-pdf me-1"></i>Generate Report
</button>
</div>
</div>
</div>
<div class="card-body">
{% if evaluation_list %}
<div class="table-responsive">
<table class="table table-striped table-hover">
<thead>
<tr>
<th width="30">
<input type="checkbox" id="selectAll" onchange="toggleSelectAll()">
</th>
<th>Employee</th>
<th>Department</th>
<th>Evaluator</th>
<th>Period</th>
<th>Score</th>
<th>Status</th>
<th>Due Date</th>
<th>Last Updated</th>
<th width="120">Actions</th>
</tr>
</thead>
<tbody>
{% for evaluation in evaluation_list %}
<tr>
<td>
<input type="checkbox" class="evaluation-checkbox" value="{{ evaluation.id }}">
</td>
<td>
<div class="d-flex align-items-center">
<div class="avatar avatar-sm me-2">
{% if evaluation.employee.photo %}
<img src="{{ evaluation.employee.photo.url }}" alt="{{ evaluation.employee.get_full_name }}" class="rounded-circle">
{% else %}
<div class="avatar-initial rounded-circle bg-primary">
{{ evaluation.employee.first_name|first }}{{ evaluation.employee.last_name|first }}
</div>
{% endif %}
</div>
<div>
<h6 class="mb-0">{{ evaluation.employee.get_full_name }}</h6>
<small class="text-muted">{{ evaluation.employee.employee_id }}</small>
</div>
</div>
</td>
<td>{{ evaluation.employee.department.name|default:"Not assigned" }}</td>
<td>
{% if evaluation.evaluator %}
<div class="d-flex align-items-center">
<div class="avatar avatar-xs me-1">
<div class="avatar-initial rounded-circle bg-secondary">
{{ evaluation.evaluator.first_name|first }}{{ evaluation.evaluator.last_name|first }}
</div>
</div>
<small>{{ evaluation.evaluator.get_full_name }}</small>
</div>
{% else %}
<span class="text-muted">Not assigned</span>
{% endif %}
</td>
<td>
<span class="badge bg-secondary">{{ evaluation.get_period_display }}</span>
</td>
<td>
{% if evaluation.overall_score %}
<div class="d-flex align-items-center">
<div class="progress me-2" style="width: 60px; height: 20px;">
<div class="progress-bar bg-{{ evaluation.score_color }}"
role="progressbar"
style="width: {{ evaluation.score_percentage }}%"
aria-valuenow="{{ evaluation.overall_score }}"
aria-valuemin="0"
aria-valuemax="5">
</div>
</div>
<span class="fw-bold">{{ evaluation.overall_score|floatformat:1 }}/5</span>
</div>
{% else %}
<span class="text-muted">Not scored</span>
{% endif %}
</td>
<td>
<span class="badge bg-{{ evaluation.status_color }}">
{{ evaluation.get_status_display }}
</span>
</td>
<td>
{% if evaluation.due_date %}
<span class="{% if evaluation.is_overdue %}text-danger{% elif evaluation.is_due_soon %}text-warning{% endif %}">
{{ evaluation.due_date|date:"M d, Y" }}
</span>
{% else %}
<span class="text-muted">No due date</span>
{% endif %}
</td>
<td>
<small class="text-muted">{{ evaluation.updated_at|date:"M d, Y" }}</small>
</td>
<td>
<div class="btn-group btn-group-sm">
<button class="btn btn-outline-primary" onclick="viewEvaluation('{{ evaluation.id }}')" title="View Details">
<i class="fa fa-eye"></i>
</button>
<button class="btn btn-outline-secondary" onclick="editEvaluation('{{ evaluation.id }}')" title="Edit">
<i class="fa fa-edit"></i>
</button>
<div class="btn-group btn-group-sm">
<button class="btn btn-outline-info dropdown-toggle" data-bs-toggle="dropdown" title="More Actions">
<i class="fa fa-ellipsis-v"></i>
</button>
<ul class="dropdown-menu">
{% if evaluation.status == 'completed' %}
<li><a class="dropdown-item" href="#" onclick="approveEvaluation('{{ evaluation.id }}')">
<i class="fa fa-check me-2"></i>Approve
</a></li>
<li><a class="dropdown-item" href="#" onclick="rejectEvaluation('{{ evaluation.id }}')">
<i class="fa fa-times me-2"></i>Reject
</a></li>
<li><hr class="dropdown-divider"></li>
{% endif %}
<li><a class="dropdown-item" href="#" onclick="duplicateEvaluation('{{ evaluation.id }}')">
<i class="fa fa-copy me-2"></i>Duplicate
</a></li>
<li><a class="dropdown-item" href="#" onclick="printEvaluation('{{ evaluation.id }}')">
<i class="fa fa-print me-2"></i>Print
</a></li>
<li><a class="dropdown-item" href="#" onclick="sendReminder('{{ evaluation.id }}')">
<i class="fa fa-bell me-2"></i>Send Reminder
</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item text-danger" href="#" onclick="deleteEvaluation('{{ evaluation.id }}')">
<i class="fa fa-trash me-2"></i>Delete
</a></li>
</ul>
</div>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- Pagination -->
{% if is_paginated %}
<nav aria-label="Evaluation pagination">
<ul class="pagination justify-content-center">
{% if page_obj.has_previous %}
<li class="page-item">
<a class="page-link" href="?page=1{% if request.GET.search %}&search={{ request.GET.search }}{% endif %}{% if request.GET.status %}&status={{ request.GET.status }}{% endif %}{% if request.GET.department %}&department={{ request.GET.department }}{% endif %}">First</a>
</li>
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.previous_page_number }}{% if request.GET.search %}&search={{ request.GET.search }}{% endif %}{% if request.GET.status %}&status={{ request.GET.status }}{% endif %}{% if request.GET.department %}&department={{ request.GET.department }}{% endif %}">Previous</a>
</li>
{% endif %}
<li class="page-item active">
<span class="page-link">{{ page_obj.number }} of {{ page_obj.paginator.num_pages }}</span>
</li>
{% if page_obj.has_next %}
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.next_page_number }}{% if request.GET.search %}&search={{ request.GET.search }}{% endif %}{% if request.GET.status %}&status={{ request.GET.status }}{% endif %}{% if request.GET.department %}&department={{ request.GET.department }}{% endif %}">Next</a>
</li>
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.paginator.num_pages }}{% if request.GET.search %}&search={{ request.GET.search }}{% endif %}{% if request.GET.status %}&status={{ request.GET.status }}{% endif %}{% if request.GET.department %}&department={{ request.GET.department }}{% endif %}">Last</a>
</li>
{% endif %}
</ul>
</nav>
{% endif %}
{% else %}
<div class="text-center py-4">
<i class="fa fa-clipboard-list fa-3x text-muted mb-3"></i>
<h5 class="text-muted">No evaluations found</h5>
<p class="text-muted">Start by creating a new performance evaluation.</p>
<button class="btn btn-primary" onclick="createEvaluation()">
<i class="fa fa-plus me-2"></i>New Evaluation
</button>
</div>
{% endif %}
</div>
</div>
</div>
</div>
</div>
</div>
<!-- New Evaluation Modal -->
<div class="modal fade" id="newEvaluationModal" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Create New Performance Evaluation</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<form id="newEvaluationForm">
{% csrf_token %}
<div class="modal-body">
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label class="form-label">Employee <span class="text-danger">*</span></label>
<select class="form-select" name="employee" required>
<option value="">Select employee...</option>
{% for employee in employees %}
<option value="{{ employee.id }}">{{ employee.get_full_name }} ({{ employee.employee_id }})</option>
{% endfor %}
</select>
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label class="form-label">Evaluator <span class="text-danger">*</span></label>
<select class="form-select" name="evaluator" required>
<option value="">Select evaluator...</option>
{% for evaluator in evaluators %}
<option value="{{ evaluator.id }}">{{ evaluator.get_full_name }}</option>
{% endfor %}
</select>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label class="form-label">Evaluation Period <span class="text-danger">*</span></label>
<select class="form-select" name="period" required>
<option value="">Select period...</option>
<option value="annual">Annual Review</option>
<option value="semi_annual">Semi-Annual Review</option>
<option value="quarterly">Quarterly Review</option>
<option value="probationary">Probationary Review</option>
<option value="special">Special Review</option>
</select>
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label class="form-label">Evaluation Template</label>
<select class="form-select" name="template">
<option value="">Select template...</option>
<option value="standard">Standard Employee</option>
<option value="clinical">Clinical Staff</option>
<option value="management">Management</option>
<option value="support">Support Staff</option>
<option value="custom">Custom</option>
</select>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label class="form-label">Review Period Start</label>
<input type="date" class="form-control" name="review_period_start">
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label class="form-label">Review Period End</label>
<input type="date" class="form-control" name="review_period_end">
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label class="form-label">Due Date</label>
<input type="date" class="form-control" name="due_date">
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label class="form-label">Priority</label>
<select class="form-select" name="priority">
<option value="normal">Normal</option>
<option value="high">High</option>
<option value="urgent">Urgent</option>
</select>
</div>
</div>
</div>
<div class="mb-3">
<label class="form-label">Evaluation Goals</label>
<textarea class="form-control" name="goals" rows="3" placeholder="Specific goals and objectives for this evaluation..."></textarea>
</div>
<div class="mb-3">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="notify_employee" id="notifyEmployee" checked>
<label class="form-check-label" for="notifyEmployee">
Notify employee about evaluation
</label>
</div>
</div>
<div class="mb-3">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="self_evaluation" id="selfEvaluation">
<label class="form-check-label" for="selfEvaluation">
Include self-evaluation component
</label>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-primary">
<i class="fa fa-plus me-2"></i>Create Evaluation
</button>
</div>
</form>
</div>
</div>
</div>
<!-- Bulk Action Modal -->
<div class="modal fade" id="bulkActionModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="bulkActionTitle">Bulk Action</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<form id="bulkActionForm">
{% csrf_token %}
<input type="hidden" name="action" id="bulkActionType">
<input type="hidden" name="evaluation_ids" id="bulkEvaluationIds">
<div class="modal-body">
<div id="bulkActionContent">
<!-- Content will be populated based on action type -->
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-primary" id="bulkActionSubmit">
<i class="fa fa-check me-2"></i>Confirm
</button>
</div>
</form>
</div>
</div>
</div>
{% endblock %}
{% block js %}
<script>
$(document).ready(function() {
setupEventHandlers();
setupFormValidation();
});
function setupEventHandlers() {
// Search form
$('#searchForm').on('submit', function(e) {
e.preventDefault();
var formData = $(this).serialize();
window.location.href = '{% url "hr:performance_evaluation" %}?' + formData;
});
// New evaluation form
$('#newEvaluationForm').on('submit', function(e) {
e.preventDefault();
createEvaluationSubmit();
});
// Bulk action form
$('#bulkActionForm').on('submit', function(e) {
e.preventDefault();
executeBulkAction();
});
}
function setupFormValidation() {
// Employee selection change
$('select[name="employee"]').on('change', function() {
var employeeId = $(this).val();
if (employeeId) {
loadEmployeeInfo(employeeId);
}
});
// Template selection change
$('select[name="template"]').on('change', function() {
var template = $(this).val();
if (template) {
loadTemplateInfo(template);
}
});
}
function createEvaluation() {
$('#newEvaluationModal').modal('show');
}
function createEvaluationSubmit() {
var formData = $('#newEvaluationForm').serialize();
$.post('{% url "hr:create_evaluation" %}', formData, function(data) {
if (data.success) {
toastr.success('Performance evaluation created successfully');
$('#newEvaluationModal').modal('hide');
location.reload();
} else {
toastr.error('Failed to create evaluation: ' + data.error);
}
});
}
function loadEmployeeInfo(employeeId) {
$.get('{% url "hr:get_employee_details" %}', {employee_id: employeeId}, function(data) {
if (data.success) {
// Auto-select appropriate evaluator (manager)
if (data.employee.manager_id) {
$('select[name="evaluator"]').val(data.employee.manager_id);
}
// Set appropriate template based on role
var template = 'standard';
if (data.employee.is_clinical) {
template = 'clinical';
} else if (data.employee.is_manager) {
template = 'management';
} else if (data.employee.is_support) {
template = 'support';
}
$('select[name="template"]').val(template);
}
});
}
function loadTemplateInfo(template) {
$.get('{% url "hr:get_evaluation_template" %}', {template: template}, function(data) {
if (data.success) {
toastr.info('Template loaded: ' + data.template.name);
}
});
}
function viewEvaluation(evaluationId) {
window.location.href = '{% url "hr:evaluation_detail" 0 %}'.replace('0', evaluationId);
}
function editEvaluation(evaluationId) {
window.location.href = '{% url "hr:evaluation_edit" 0 %}'.replace('0', evaluationId);
}
function approveEvaluation(evaluationId) {
$.post('{% url "hr:approve_evaluation" %}', {
evaluation_id: evaluationId,
csrfmiddlewaretoken: '{{ csrf_token }}'
}, function(data) {
if (data.success) {
toastr.success('Evaluation approved successfully');
location.reload();
} else {
toastr.error('Failed to approve evaluation: ' + data.error);
}
});
}
function rejectEvaluation(evaluationId) {
var reason = prompt('Please provide a reason for rejection:');
if (reason) {
$.post('{% url "hr:reject_evaluation" %}', {
evaluation_id: evaluationId,
reason: reason,
csrfmiddlewaretoken: '{{ csrf_token }}'
}, function(data) {
if (data.success) {
toastr.success('Evaluation rejected');
location.reload();
} else {
toastr.error('Failed to reject evaluation: ' + data.error);
}
});
}
}
function duplicateEvaluation(evaluationId) {
$.post('{% url "hr:duplicate_evaluation" %}', {
evaluation_id: evaluationId,
csrfmiddlewaretoken: '{{ csrf_token }}'
}, function(data) {
if (data.success) {
toastr.success('Evaluation duplicated successfully');
location.reload();
} else {
toastr.error('Failed to duplicate evaluation: ' + data.error);
}
});
}
function printEvaluation(evaluationId) {
window.open('{% url "hr:print_evaluation" 0 %}'.replace('0', evaluationId), '_blank');
}
function sendReminder(evaluationId) {
$.post('{% url "hr:send_evaluation_reminder" %}', {
evaluation_id: evaluationId,
csrfmiddlewaretoken: '{{ csrf_token }}'
}, function(data) {
if (data.success) {
toastr.success('Reminder sent successfully');
} else {
toastr.error('Failed to send reminder: ' + data.error);
}
});
}
function deleteEvaluation(evaluationId) {
if (confirm('Are you sure you want to delete this evaluation? This action cannot be undone.')) {
$.post('{% url "hr:delete_evaluation" %}', {
evaluation_id: evaluationId,
csrfmiddlewaretoken: '{{ csrf_token }}'
}, function(data) {
if (data.success) {
toastr.success('Evaluation deleted successfully');
location.reload();
} else {
toastr.error('Failed to delete evaluation: ' + data.error);
}
});
}
}
function toggleSelectAll() {
var selectAll = $('#selectAll').prop('checked');
$('.evaluation-checkbox').prop('checked', selectAll);
}
function getSelectedEvaluations() {
var selected = [];
$('.evaluation-checkbox:checked').each(function() {
selected.push($(this).val());
});
return selected;
}
function bulkAction(action) {
var selected = getSelectedEvaluations();
if (selected.length === 0) {
toastr.warning('Please select at least one evaluation');
return;
}
$('#bulkActionType').val(action);
$('#bulkEvaluationIds').val(selected.join(','));
var title = '';
var content = '';
var submitText = '';
switch (action) {
case 'approve':
title = 'Approve Selected Evaluations';
content = '<p>Are you sure you want to approve the selected evaluations?</p>' +
'<div class="mb-3">' +
'<label class="form-label">Approval Notes</label>' +
'<textarea class="form-control" name="approval_notes" rows="3" placeholder="Optional approval notes..."></textarea>' +
'</div>';
submitText = 'Approve';
break;
case 'remind':
title = 'Send Reminders';
content = '<p>Send reminder notifications for the selected evaluations?</p>' +
'<div class="mb-3">' +
'<label class="form-label">Custom Message</label>' +
'<textarea class="form-control" name="reminder_message" rows="3" placeholder="Optional custom message..."></textarea>' +
'</div>';
submitText = 'Send Reminders';
break;
}
$('#bulkActionTitle').text(title);
$('#bulkActionContent').html(content);
$('#bulkActionSubmit').html('<i class="fa fa-check me-2"></i>' + submitText);
$('#bulkActionModal').modal('show');
}
function executeBulkAction() {
var formData = $('#bulkActionForm').serialize();
$.post('{% url "hr:bulk_evaluation_action" %}', formData, function(data) {
if (data.success) {
toastr.success('Bulk action completed successfully');
$('#bulkActionModal').modal('hide');
location.reload();
} else {
toastr.error('Failed to execute bulk action: ' + data.error);
}
});
}
function generateReport() {
var params = new URLSearchParams(window.location.search);
params.set('report', 'true');
window.open('{% url "hr:evaluation_report" %}?' + params.toString(), '_blank');
}
function resetFilters() {
window.location.href = '{% url "hr:performance_evaluation" %}';
}
function exportEvaluations() {
var params = new URLSearchParams(window.location.search);
params.set('export', 'true');
window.location.href = '{% url "hr:performance_evaluation" %}?' + params.toString();
}
function viewAnalytics() {
window.location.href = '{% url "hr:evaluation_analytics" %}';
}
</script>
<style>
.avatar {
width: 32px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
}
.avatar-sm {
width: 24px;
height: 24px;
font-size: 0.75rem;
}
.avatar-xs {
width: 20px;
height: 20px;
font-size: 0.625rem;
}
.avatar img {
width: 100%;
height: 100%;
object-fit: cover;
}
.avatar-initial {
background-color: #6c757d;
color: white;
font-weight: 600;
font-size: 0.875rem;
}
.progress {
background-color: #e9ecef;
}
.progress-bar {
transition: width 0.3s ease;
}
.card-tools {
margin-left: auto;
}
.btn-group-sm .btn {
padding: 0.25rem 0.5rem;
font-size: 0.875rem;
}
.table th {
border-top: none;
font-weight: 600;
color: #495057;
background-color: #f8f9fa;
}
.table-hover tbody tr:hover {
background-color: rgba(0, 0, 0, 0.025);
}
.badge {
font-size: 0.75em;
font-weight: 500;
}
.text-danger {
color: #dc3545 !important;
}
.text-warning {
color: #fd7e14 !important;
}
.text-success {
color: #198754 !important;
}
.dropdown-menu {
border: 1px solid #dee2e6;
box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
}
.dropdown-item:hover {
background-color: #f8f9fa;
}
.modal-header {
border-bottom: 1px solid #dee2e6;
}
.modal-footer {
border-top: 1px solid #dee2e6;
}
.form-check-input:checked {
background-color: #0d6efd;
border-color: #0d6efd;
}
.score-excellent { background-color: #198754 !important; }
.score-good { background-color: #20c997 !important; }
.score-satisfactory { background-color: #ffc107 !important; }
.score-needs-improvement { background-color: #fd7e14 !important; }
.score-unsatisfactory { background-color: #dc3545 !important; }
@media (max-width: 768px) {
.btn-group {
flex-direction: column;
}
.btn-group .btn {
margin-bottom: 0.25rem;
}
.table-responsive {
font-size: 0.875rem;
}
.avatar {
width: 24px;
height: 24px;
}
}
</style>
{% endblock %}