Files
multiarch-docker-images/automatic-pdf-renamer/web/maintenance.js
T

105 lines
4.5 KiB
JavaScript

const rebuildButton = document.getElementById('rebuild-button');
const checkButton = document.getElementById('check-button');
const actionButtons = [rebuildButton, checkButton];
const runAction = async ({ operation, progress, status, endpoint, method, confirmation, getResult }) => {
if (!window.confirm(confirmation)) return;
actionButtons.forEach((actionButton) => { actionButton.disabled = true; });
operation.hidden = false;
progress.hidden = false;
progress.removeAttribute('value');
status.textContent = 'Running...';
try {
const response = await fetch(endpoint, { method });
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const result = await response.json();
progress.value = 1;
status.textContent = getResult(result);
} catch (error) {
progress.hidden = true;
status.textContent = 'The action failed. Check the API server and storage backend.';
console.error(error);
} finally {
actionButtons.forEach((actionButton) => { actionButton.disabled = false; });
}
};
rebuildButton.addEventListener('click', () => runAction({
operation: document.getElementById('rebuild-operation'),
progress: document.getElementById('rebuild-progress'),
status: document.getElementById('rebuild-status'),
endpoint: '/consistency/rebuild',
method: 'POST',
confirmation: 'Rebuild the database from sidecar files? Existing database records will be replaced.',
getResult: (result) => `Database rebuilt from ${result.count} sidecar file${result.count === 1 ? '' : 's'}.`,
}));
checkButton.addEventListener('click', () => runAction({
operation: document.getElementById('check-operation'),
progress: document.getElementById('check-progress'),
status: document.getElementById('check-status'),
endpoint: '/consistency',
method: 'GET',
confirmation: 'Run a consistency check? This scans metadata and database records against storage.',
getResult: (anomalies) => anomalies.length
? `Consistency check complete: ${anomalies.length} issue${anomalies.length === 1 ? '' : 's'} found.`
: 'Consistency check complete: no issues found.',
}));
const trainModelButton = document.getElementById('train-model-button');
const modelTrainingOperation = document.getElementById('model-training-operation');
const modelTrainingProgress = document.getElementById('model-training-progress');
const modelsStatus = document.getElementById('models-status');
const modelsInventoryStatus = document.getElementById('models-inventory-status');
const sleep = (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds));
const pollModelTraining = async (jobId) => {
while (true) {
const response = await fetch(`/jobs/${encodeURIComponent(jobId)}`);
const result = await response.json();
if (!response.ok) throw new Error(result.detail || `HTTP ${response.status}`);
modelTrainingProgress.value = Number(result.progress || 0);
modelsStatus.textContent = result.message || result.stage || 'Training models…';
if (result.status === 'completed') {
modelTrainingProgress.value = 100;
modelsInventoryStatus.textContent = 'All models were replaced successfully. Previous model artifacts have been removed.';
return;
}
if (result.status === 'failed') {
throw new Error(result.message || 'Model retraining failed.');
}
await sleep(1000);
}
};
trainModelButton.addEventListener('click', async () => {
if (!window.confirm('Retrain all models from validated documents? The current models will be replaced after the complete training succeeds.')) return;
trainModelButton.disabled = true;
actionButtons.forEach((button) => { button.disabled = true; });
modelTrainingOperation.hidden = false;
modelTrainingProgress.value = 0;
modelsInventoryStatus.textContent = '';
modelsStatus.textContent = 'Starting full model retraining…';
try {
const response = await fetch('/models/train', { method: 'POST' });
const result = await response.json();
if (!response.ok) throw new Error(result.detail || `HTTP ${response.status}`);
await pollModelTraining(result.job_id);
modelsStatus.textContent = 'Model retraining completed.';
} catch (error) {
modelsStatus.textContent = `Model retraining failed: ${error.message}`;
modelsInventoryStatus.textContent = 'The previous model set should remain active if training failed before replacement.';
console.error(error);
} finally {
trainModelButton.disabled = false;
actionButtons.forEach((button) => { button.disabled = false; });
}
});