update changes
This commit is contained in:
parent
672551cd0a
commit
b479fee7c9
|
|
@ -23,7 +23,7 @@ class ATSController(http.Controller):
|
||||||
|
|
||||||
@http.route('/myATS/page/<string:page>', type='http', auth='user', website=True)
|
@http.route('/myATS/page/<string:page>', type='http', auth='user', website=True)
|
||||||
def render_partial_content(self, page, **kwargs):
|
def render_partial_content(self, page, **kwargs):
|
||||||
if page == "job_requests":
|
if page in ["job_requests","jobs"]:
|
||||||
jobs = request.env['hr.job.recruitment'].search([], order='create_date desc')
|
jobs = request.env['hr.job.recruitment'].search([], order='create_date desc')
|
||||||
return request.render('hr_recruitment_web_app.job_list_partial_page', {'jobs': jobs})
|
return request.render('hr_recruitment_web_app.job_list_partial_page', {'jobs': jobs})
|
||||||
elif page == "applicants":
|
elif page == "applicants":
|
||||||
|
|
@ -56,6 +56,17 @@ class ATSController(http.Controller):
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@http.route('/myATS/applicant/update_stage', type='json', auth='user')
|
||||||
|
def update_applicant_stage(self, applicant_id, stage_id, **kwargs):
|
||||||
|
try:
|
||||||
|
applicant = request.env['hr.applicant'].browse(int(applicant_id))
|
||||||
|
if applicant.exists():
|
||||||
|
applicant.write({'stage_id': int(stage_id)})
|
||||||
|
return {'success': True}
|
||||||
|
return {'success': False, 'error': 'Applicant not found'}
|
||||||
|
except Exception as e:
|
||||||
|
return {'success': False, 'error': str(e)}
|
||||||
|
|
||||||
@http.route('/myATS/job/create', type='http', auth='user', methods=['POST'], csrf=False)
|
@http.route('/myATS/job/create', type='http', auth='user', methods=['POST'], csrf=False)
|
||||||
def create_job_request(self, **post):
|
def create_job_request(self, **post):
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
|
|
@ -493,6 +493,71 @@
|
||||||
border: 1px solid var(--border-color) !important;
|
border: 1px solid var(--border-color) !important;
|
||||||
box-shadow: 0 2px 5px var(--shadow-color) !important;
|
box-shadow: 0 2px 5px var(--shadow-color) !important;
|
||||||
}
|
}
|
||||||
|
/* Base button styling */
|
||||||
|
.btn-stage {
|
||||||
|
position: relative;
|
||||||
|
min-width: 100px;
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
margin: 0 2px;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
font-weight: 500;
|
||||||
|
text-align: center;
|
||||||
|
transition: all 0.25s ease;
|
||||||
|
cursor: pointer;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Current stage styling */
|
||||||
|
.btn-stage-current {
|
||||||
|
background-color: #0d6efd; /* Primary blue */
|
||||||
|
color: white;
|
||||||
|
border-color: #0d6efd;
|
||||||
|
box-shadow: 0 2px 5px rgba(13, 110, 253, 0.3);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Other stage options */
|
||||||
|
.btn-stage-option {
|
||||||
|
background-color: white;
|
||||||
|
color: #555;
|
||||||
|
border-color: #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hover effects */
|
||||||
|
.btn-stage-option:hover {
|
||||||
|
background-color: #f0f7ff; /* Very light blue */
|
||||||
|
border-color: #0d6efd;
|
||||||
|
color: #0d6efd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-stage-current:hover {
|
||||||
|
background-color: #0b5ed7; /* Slightly darker blue */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Active state */
|
||||||
|
.btn-stage:active {
|
||||||
|
transform: translateY(1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Focus state */
|
||||||
|
.btn-stage:focus {
|
||||||
|
box-shadow: 0 0 0 3px rgba(13, 110, 253, 0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Disabled state during loading */
|
||||||
|
.btn-stage.processing {
|
||||||
|
opacity: 0.7;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Responsive adjustments */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.btn-stage {
|
||||||
|
min-width: 80px;
|
||||||
|
padding: 0.4rem 0.6rem;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
margin: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -248,20 +248,20 @@ function initApplicantsPage() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// Close modal when clicking outside of it
|
// Close modal when clicking outside of it
|
||||||
applicantModal.addEventListener('click', function(e) {
|
// applicantModal.addEventListener('click', function(e) {
|
||||||
if (e.target === applicantModal) {
|
// if (e.target === applicantModal) {
|
||||||
applicantModal.classList.remove('show');
|
// applicantModal.classList.remove('show');
|
||||||
setTimeout(() => {
|
// setTimeout(() => {
|
||||||
applicantModal.style.display = 'none';
|
// applicantModal.style.display = 'none';
|
||||||
}, 300);
|
// }, 300);
|
||||||
document.body.style.overflow = '';
|
// document.body.style.overflow = '';
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
// File Upload Handling
|
// File Upload Handling
|
||||||
const resumeUpload = document.getElementById('resume-upload');
|
const resumeUpload = document.getElementById('resume-upload');
|
||||||
const resumeDropzone = document.getElementById('resume-dropzone');
|
const resumeDropzone = document.getElementById('resume-dropzone');
|
||||||
const resumePreview = document.getElementById('resume-preview');
|
const resumePreview = document.getElementById('resume-preview');
|
||||||
const resumePlaceholder = resumePreview.querySelector('.resume-preview-placeholder');
|
const resumePlaceholder = document.querySelector('.resume-preview-placeholder');
|
||||||
const resumeIframe = document.getElementById('resume-iframe');
|
const resumeIframe = document.getElementById('resume-iframe');
|
||||||
const resumeImage = document.getElementById('resume-image');
|
const resumeImage = document.getElementById('resume-image');
|
||||||
const unsupportedFormat = document.getElementById('unsupported-format');
|
const unsupportedFormat = document.getElementById('unsupported-format');
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||||
initNavigation();
|
initNavigation();
|
||||||
|
|
||||||
// Load default page based on URL hash or default to jobs
|
// Load default page based on URL hash or default to jobs
|
||||||
loadPage(window.location.hash || "#jobs");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -47,6 +46,61 @@ function initTheme() {
|
||||||
applyTheme(currentTheme === 'dark' ? 'light' : 'dark');
|
applyTheme(currentTheme === 'dark' ? 'light' : 'dark');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
document.querySelectorAll('.btn-stage').forEach(button => {
|
||||||
|
button.addEventListener('click', function() {
|
||||||
|
const container = this.closest('.stage-selector');
|
||||||
|
const buttons = container.querySelectorAll('.btn-stage');
|
||||||
|
const applicantId = container.dataset.applicantId;
|
||||||
|
const newStageId = this.dataset.stageId;
|
||||||
|
|
||||||
|
// Visual feedback
|
||||||
|
buttons.forEach(btn => {
|
||||||
|
btn.classList.remove('btn-stage-current');
|
||||||
|
btn.classList.add('btn-stage-option');
|
||||||
|
});
|
||||||
|
|
||||||
|
this.classList.remove('btn-stage-option');
|
||||||
|
this.classList.add('btn-stage-current', 'processing');
|
||||||
|
|
||||||
|
// AJAX call to update stage
|
||||||
|
fetch('/update_stage', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'X-CSRF-TOKEN': getCSRFToken()
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
applicant_id: applicantId,
|
||||||
|
stage_id: newStageId
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
if (data.success) {
|
||||||
|
showNotification('Stage updated successfully!', 'success');
|
||||||
|
} else {
|
||||||
|
throw new Error(data.error || 'Update failed');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error("Error:", error);
|
||||||
|
showNotification('Failed to update stage', 'danger');
|
||||||
|
// Revert visual state if needed
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.classList.remove('processing');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function getCSRFToken() {
|
||||||
|
return document.querySelector('meta[name="csrf-token"]').content;
|
||||||
|
}
|
||||||
|
|
||||||
|
function showNotification(message, type) {
|
||||||
|
// Your notification implementation
|
||||||
|
}
|
||||||
|
|
||||||
// Watch for system theme changes
|
// Watch for system theme changes
|
||||||
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => {
|
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => {
|
||||||
|
|
@ -171,4 +225,5 @@ function initNavigation() {
|
||||||
|
|
||||||
// Initial highlight
|
// Initial highlight
|
||||||
highlightActiveMenu();
|
highlightActiveMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -118,7 +118,7 @@ function initCandidatesPage() {
|
||||||
const resumeUpload = document.getElementById('resume-upload');
|
const resumeUpload = document.getElementById('resume-upload');
|
||||||
const resumeDropzone = document.getElementById('resume-dropzone');
|
const resumeDropzone = document.getElementById('resume-dropzone');
|
||||||
const resumePreview = document.getElementById('resume-preview');
|
const resumePreview = document.getElementById('resume-preview');
|
||||||
const resumePlaceholder = resumePreview.querySelector('.resume-preview-placeholder');
|
const resumePlaceholder = document.querySelector('.resume-preview-placeholder');
|
||||||
const resumeIframe = document.getElementById('resume-iframe');
|
const resumeIframe = document.getElementById('resume-iframe');
|
||||||
const resumeImage = document.getElementById('resume-image');
|
const resumeImage = document.getElementById('resume-image');
|
||||||
const unsupportedFormat = document.getElementById('unsupported-format');
|
const unsupportedFormat = document.getElementById('unsupported-format');
|
||||||
|
|
@ -161,15 +161,15 @@ function initCandidatesPage() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
candidateModal.addEventListener('click', function(e) {
|
// candidateModal.addEventListener('click', function(e) {
|
||||||
if (e.target === candidateModal) {
|
// if (e.target === candidateModal) {
|
||||||
candidateModal.classList.remove('show');
|
// candidateModal.classList.remove('show');
|
||||||
setTimeout(() => {
|
// setTimeout(() => {
|
||||||
candidateModal.style.display = 'none';
|
// candidateModal.style.display = 'none';
|
||||||
}, 300);
|
// }, 300);
|
||||||
document.body.style.overflow = '';
|
// document.body.style.overflow = '';
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
|
|
||||||
function formatUserOption(user) {
|
function formatUserOption(user) {
|
||||||
if (!user.id) return user.text;
|
if (!user.id) return user.text;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
/** @odoo-module */
|
|
||||||
|
|
||||||
// Define all your page initialization functions first
|
// Define all your page initialization functions first
|
||||||
function initJobListPage() {
|
function initJobListPage() {
|
||||||
console.log("Job List Page JS Loaded");
|
console.log("Job List Page JS Loaded");
|
||||||
|
|
|
||||||
|
|
@ -243,6 +243,16 @@
|
||||||
<span t-esc="applicant.current_location or 'Location not specified'"/>
|
<span t-esc="applicant.current_location or 'Location not specified'"/>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="stage-selector btn-group" role="group" t-att-data-applicant-id="applicant.id">
|
||||||
|
<t t-foreach="applicant.hr_job_recruitment.recruitment_stage_ids" t-as="stage">
|
||||||
|
<button type="button"
|
||||||
|
class="btn btn-stage"
|
||||||
|
t-att-class="'btn btn-stage ' +
|
||||||
|
('btn-stage-current' if applicant.stage_id.id == stage.id else 'btn-stage-option')"
|
||||||
|
t-att-data-stage-id="stage.id"
|
||||||
|
t-esc="stage.display_name"/>
|
||||||
|
</t>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="ats-avatar">
|
<div class="ats-avatar">
|
||||||
<div class="avatar-wrapper">
|
<div class="avatar-wrapper">
|
||||||
|
|
|
||||||
|
|
@ -28,13 +28,10 @@
|
||||||
<script type="text/javascript" src="/hr_recruitment_web_app/static/src/js/ats.js"></script>
|
<script type="text/javascript" src="/hr_recruitment_web_app/static/src/js/ats.js"></script>
|
||||||
<!-- <script type="text/javascript" src="/hr_recruitment_web_app/static/src/js/candidates.js"></script>-->
|
<!-- <script type="text/javascript" src="/hr_recruitment_web_app/static/src/js/candidates.js"></script>-->
|
||||||
<script type="text/javascript" src="/hr_recruitment_web_app/static/src/js/job_requests.js?v=20"></script>
|
<script type="text/javascript" src="/hr_recruitment_web_app/static/src/js/job_requests.js?v=20"></script>
|
||||||
<script type="text/javascript" src="/hr_recruitment_web_app/static/src/js/applicants.js?v=8"></script>
|
<script type="text/javascript" src="/hr_recruitment_web_app/static/src/js/applicants.js?v=10"></script>
|
||||||
<script type="text/javascript" src="/hr_recruitment_web_app/static/src/js/candidates.js?v=6"></script>
|
<script type="text/javascript" src="/hr_recruitment_web_app/static/src/js/candidates.js?v=6"></script>
|
||||||
<script type="text/javascript"
|
<script type="text/javascript"
|
||||||
src="https://cdn.ckeditor.com/ckeditor5/39.0.0/classic/ckeditor.js"></script>
|
src="https://cdn.ckeditor.com/ckeditor5/39.0.0/classic/ckeditor.js"></script>
|
||||||
<link rel="stylesheet" href="/hr_recruitment_web_app/static/src/css/select2.min.css"/>
|
|
||||||
<script type="text/javascript"
|
|
||||||
src="/hr_recruitment_web_app/static/src/js/select2.main.js"></script>
|
|
||||||
</head>
|
</head>
|
||||||
<body class="ats-app">
|
<body class="ats-app">
|
||||||
<div class="layout-container">
|
<div class="layout-container">
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue