feat: add template selector to batch detail for CV generation
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -197,6 +197,8 @@ CREATE TABLE IF NOT EXISTS cv_batches (
|
|||||||
-- JSON array of positions extracted from the document
|
-- JSON array of positions extracted from the document
|
||||||
-- [{job_title, num_positions, required_skills, required_years, required_certs, description}]
|
-- [{job_title, num_positions, required_skills, required_years, required_certs, description}]
|
||||||
positions JSONB DEFAULT '[]',
|
positions JSONB DEFAULT '[]',
|
||||||
|
-- Selected Carbone template ID for CV generation
|
||||||
|
template_id TEXT,
|
||||||
-- draft = still working, active = matching done, exported = CVs generated
|
-- draft = still working, active = matching done, exported = CVs generated
|
||||||
status VARCHAR(50) DEFAULT 'draft',
|
status VARCHAR(50) DEFAULT 'draft',
|
||||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
|||||||
6
main.py
6
main.py
@@ -913,12 +913,12 @@ async def get_batch(batch_id: str):
|
|||||||
|
|
||||||
@app.put("/api/batches/{batch_id}")
|
@app.put("/api/batches/{batch_id}")
|
||||||
async def update_batch(batch_id: str, request: Request):
|
async def update_batch(batch_id: str, request: Request):
|
||||||
"""Update batch name/description."""
|
"""Update batch name/description/template."""
|
||||||
body = await request.json()
|
body = await request.json()
|
||||||
row = db.execute(
|
row = db.execute(
|
||||||
"""UPDATE cv_batches SET name = %s, description = %s, updated_at = NOW()
|
"""UPDATE cv_batches SET name = %s, description = %s, template_id = %s, updated_at = NOW()
|
||||||
WHERE id = %s RETURNING *""",
|
WHERE id = %s RETURNING *""",
|
||||||
(body.get("name"), body.get("description"), batch_id)
|
(body.get("name"), body.get("description"), body.get("template_id"), batch_id)
|
||||||
)
|
)
|
||||||
if not row:
|
if not row:
|
||||||
raise HTTPException(404, "Batch not found")
|
raise HTTPException(404, "Batch not found")
|
||||||
|
|||||||
@@ -143,6 +143,17 @@ async function uploadBatchDoc(file) {
|
|||||||
// BATCH DETAIL VIEW
|
// BATCH DETAIL VIEW
|
||||||
// ============================================================
|
// ============================================================
|
||||||
let currentBatch = null;
|
let currentBatch = null;
|
||||||
|
let batchTemplates = [];
|
||||||
|
|
||||||
|
async function loadBatchTemplates() {
|
||||||
|
try {
|
||||||
|
const resp = await fetch('http://' + location.hostname + ':8771/api/carbone/templates');
|
||||||
|
const data = await resp.json();
|
||||||
|
batchTemplates = data.templates || [];
|
||||||
|
} catch (e) {
|
||||||
|
batchTemplates = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function openBatch(batchId) {
|
async function openBatch(batchId) {
|
||||||
currentBatchId = batchId;
|
currentBatchId = batchId;
|
||||||
@@ -151,6 +162,8 @@ async function openBatch(batchId) {
|
|||||||
detail.style.display = 'block';
|
detail.style.display = 'block';
|
||||||
detail.innerHTML = '<div class="loading">Loading batch...</div>';
|
detail.innerHTML = '<div class="loading">Loading batch...</div>';
|
||||||
|
|
||||||
|
await loadBatchTemplates();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const resp = await fetch('/api/batches/' + batchId);
|
const resp = await fetch('/api/batches/' + batchId);
|
||||||
const data = await resp.json();
|
const data = await resp.json();
|
||||||
@@ -226,6 +239,12 @@ function renderBatchDetail(data) {
|
|||||||
positionsHtml += '</div>';
|
positionsHtml += '</div>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Build template selector options
|
||||||
|
const currentTemplateId = batch.template_id || '';
|
||||||
|
const templateOptions = batchTemplates.map(t =>
|
||||||
|
'<option value="' + t.id + '"' + (t.id === currentTemplateId ? ' selected' : '') + '>' + escapeHtml(t.name) + '</option>'
|
||||||
|
).join('');
|
||||||
|
|
||||||
document.getElementById('batch-detail-view').innerHTML = `
|
document.getElementById('batch-detail-view').innerHTML = `
|
||||||
<div class="flex-between mb-16">
|
<div class="flex-between mb-16">
|
||||||
<div>
|
<div>
|
||||||
@@ -239,10 +258,40 @@ function renderBatchDetail(data) {
|
|||||||
<button class="btn btn-outline" onclick="closeBatchDetail()">Back</button>
|
<button class="btn btn-outline" onclick="closeBatchDetail()">Back</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="card mb-16">
|
||||||
|
<div class="form-group" style="margin:0">
|
||||||
|
<label>Template for CV Generation</label>
|
||||||
|
<div class="flex gap-8">
|
||||||
|
<select id="batch-template-select" style="flex:1" onchange="saveBatchTemplate()">
|
||||||
|
<option value="">— Select a template —</option>
|
||||||
|
${templateOptions}
|
||||||
|
</select>
|
||||||
|
${batchTemplates.length === 0 ? '<span class="text-muted text-sm">No templates uploaded. Go to Templates page to add one.</span>' : ''}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
${positionsHtml}
|
${positionsHtml}
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function saveBatchTemplate() {
|
||||||
|
const templateId = document.getElementById('batch-template-select').value;
|
||||||
|
try {
|
||||||
|
await fetch('/api/batches/' + currentBatchId, {
|
||||||
|
method: 'PUT',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({
|
||||||
|
name: currentBatch.batch.name,
|
||||||
|
description: currentBatch.batch.description,
|
||||||
|
template_id: templateId
|
||||||
|
})
|
||||||
|
});
|
||||||
|
toast('Template saved for this batch');
|
||||||
|
} catch (e) {
|
||||||
|
toast('Error saving template: ' + e.message, 'error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function closeBatchDetail() {
|
function closeBatchDetail() {
|
||||||
document.getElementById('batches-list-view').style.display = 'block';
|
document.getElementById('batches-list-view').style.display = 'block';
|
||||||
document.getElementById('batch-detail-view').style.display = 'none';
|
document.getElementById('batch-detail-view').style.display = 'none';
|
||||||
|
|||||||
@@ -152,6 +152,6 @@
|
|||||||
|
|
||||||
<script src="/static/app.js?v=17"></script>
|
<script src="/static/app.js?v=17"></script>
|
||||||
<script src="/static/carbone.js?v=16"></script>
|
<script src="/static/carbone.js?v=16"></script>
|
||||||
<script src="/static/batches.js?v=1"></script>
|
<script src="/static/batches.js?v=2"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
Reference in New Issue
Block a user