Spaces:
Sleeping
Sleeping
Upload cross_reading/cross_readers.js with huggingface_hub
Browse files- cross_reading/cross_readers.js +153 -47
cross_reading/cross_readers.js
CHANGED
|
@@ -23,56 +23,45 @@ function loadData() {
|
|
| 23 |
// Masquer la section d'aide
|
| 24 |
document.getElementById('helpSection').style.display = 'none';
|
| 25 |
|
| 26 |
-
// Charger les évaluations
|
| 27 |
fetch('/api/evaluations')
|
| 28 |
.then(response => {
|
| 29 |
if (!response.ok) {
|
| 30 |
-
|
|
|
|
|
|
|
| 31 |
}
|
| 32 |
return response.json();
|
| 33 |
})
|
| 34 |
.then(data => {
|
| 35 |
allEvaluations = data.evaluations || [];
|
| 36 |
-
console.log(`${allEvaluations.length} évaluations chargées
|
| 37 |
|
| 38 |
if (allEvaluations.length === 0) {
|
| 39 |
-
console.warn('Aucune évaluation trouvée
|
| 40 |
showWarningMessage('Aucune donnée d\'évaluation trouvée. Générer des données de test pour commencer.');
|
| 41 |
document.getElementById('helpSection').style.display = 'block';
|
| 42 |
} else {
|
| 43 |
document.getElementById('warningMessage').style.display = 'none';
|
| 44 |
}
|
| 45 |
|
| 46 |
-
// Charger les scénarios
|
| 47 |
-
return fetch('/api/scenarios')
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
if (!response.ok) {
|
| 51 |
-
throw new Error(`API scenarios non disponible (${response.status})`);
|
| 52 |
-
}
|
| 53 |
-
return response.json();
|
| 54 |
})
|
| 55 |
.then(data => {
|
| 56 |
scenariosData = data.scenarios || [];
|
| 57 |
-
console.log(`${scenariosData.length} scénarios chargés
|
| 58 |
-
|
| 59 |
-
if (scenariosData.length === 0) {
|
| 60 |
-
console.warn('Aucun scénario trouvé');
|
| 61 |
-
}
|
| 62 |
|
| 63 |
-
// Charger les reviews
|
| 64 |
-
return fetch('/api/reviews')
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
if (!response.ok) {
|
| 68 |
-
console.log('API reviews non disponible, utilisation d\'une structure vide');
|
| 69 |
-
return { reviews: [] };
|
| 70 |
-
}
|
| 71 |
-
return response.json();
|
| 72 |
})
|
| 73 |
.then(data => {
|
| 74 |
reviewsData = data.reviews || [];
|
| 75 |
-
console.log(`${reviewsData.length} reviews chargés
|
| 76 |
|
| 77 |
// Traiter les données
|
| 78 |
processEvaluations();
|
|
@@ -83,7 +72,7 @@ function loadData() {
|
|
| 83 |
showErrorMessage(`Erreur de chargement: ${error.message}<br>
|
| 84 |
<br>
|
| 85 |
<strong>Solutions possibles :</strong><br>
|
| 86 |
-
1. Vérifiez que
|
| 87 |
2. Générez des données de test avec le bouton ci-dessous<br>
|
| 88 |
3. Vérifiez la console du navigateur (F12) pour plus de détails<br>
|
| 89 |
<br>
|
|
@@ -105,19 +94,21 @@ function generateTestData() {
|
|
| 105 |
|
| 106 |
showLoadingMessage('Génération des données de test...');
|
| 107 |
|
|
|
|
| 108 |
fetch('/api/generate_test_data')
|
| 109 |
.then(response => {
|
| 110 |
if (!response.ok) {
|
| 111 |
-
|
|
|
|
| 112 |
}
|
| 113 |
return response.json();
|
| 114 |
})
|
| 115 |
.then(data => {
|
| 116 |
console.log('Données de test générées:', data);
|
| 117 |
showSuccessMessage(`✅ Données de test générées avec succès !<br>
|
| 118 |
-
- ${data.evaluations} évaluations<br>
|
| 119 |
-
- ${data.scenarios} scénarios<br>
|
| 120 |
-
- ${data.reviews} reviews`);
|
| 121 |
|
| 122 |
// Recharger les données
|
| 123 |
setTimeout(() => {
|
|
@@ -126,8 +117,92 @@ function generateTestData() {
|
|
| 126 |
})
|
| 127 |
.catch(error => {
|
| 128 |
console.error('Erreur génération données test:', error);
|
| 129 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 130 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 131 |
}
|
| 132 |
|
| 133 |
// ================= TRAITEMENT DES DONNÉES =================
|
|
@@ -190,7 +265,7 @@ function processEvaluations() {
|
|
| 190 |
|
| 191 |
// Assurer un scénario ID
|
| 192 |
if (!eval.scenario_id && eval.scenario_id !== 0) {
|
| 193 |
-
eval.scenario_id =
|
| 194 |
}
|
| 195 |
});
|
| 196 |
|
|
@@ -710,7 +785,8 @@ function saveReview() {
|
|
| 710 |
original_comment: evaluation.comment,
|
| 711 |
decision: decision,
|
| 712 |
review_comment: reviewComment,
|
| 713 |
-
reviewer: 'Expert Reviewer'
|
|
|
|
| 714 |
};
|
| 715 |
|
| 716 |
// Envoyer au serveur via API
|
|
@@ -721,18 +797,47 @@ function saveReview() {
|
|
| 721 |
},
|
| 722 |
body: JSON.stringify(reviewData)
|
| 723 |
})
|
| 724 |
-
.then(response =>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 725 |
.then(data => {
|
| 726 |
if (data.status === 'ok') {
|
| 727 |
-
//
|
| 728 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 729 |
} else {
|
| 730 |
throw new Error(data.error || 'Erreur inconnue');
|
| 731 |
}
|
| 732 |
})
|
| 733 |
-
.
|
| 734 |
-
|
| 735 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 736 |
|
| 737 |
// Mettre à jour l'affichage
|
| 738 |
filterAllEvaluations();
|
|
@@ -740,11 +845,11 @@ function saveReview() {
|
|
| 740 |
// Fermer la modale
|
| 741 |
closeReviewModal();
|
| 742 |
|
| 743 |
-
showSuccessMessage(`✅ Review sauvegardé
|
| 744 |
-
|
| 745 |
-
|
| 746 |
-
|
| 747 |
-
|
| 748 |
});
|
| 749 |
}
|
| 750 |
|
|
@@ -1120,4 +1225,5 @@ window.showScenarioDetails = showScenarioDetails;
|
|
| 1120 |
window.openReviewModal = openReviewModal;
|
| 1121 |
window.closeReviewModal = closeReviewModal;
|
| 1122 |
window.saveReview = saveReview;
|
| 1123 |
-
window.generateTestData = generateTestData;
|
|
|
|
|
|
| 23 |
// Masquer la section d'aide
|
| 24 |
document.getElementById('helpSection').style.display = 'none';
|
| 25 |
|
| 26 |
+
// Charger les évaluations
|
| 27 |
fetch('/api/evaluations')
|
| 28 |
.then(response => {
|
| 29 |
if (!response.ok) {
|
| 30 |
+
console.warn('API /api/evaluations non disponible, utilisation des données locales');
|
| 31 |
+
// Charger depuis le fichier local
|
| 32 |
+
return fetch('trust_stats.json').then(r => r.json());
|
| 33 |
}
|
| 34 |
return response.json();
|
| 35 |
})
|
| 36 |
.then(data => {
|
| 37 |
allEvaluations = data.evaluations || [];
|
| 38 |
+
console.log(`${allEvaluations.length} évaluations chargées`);
|
| 39 |
|
| 40 |
if (allEvaluations.length === 0) {
|
| 41 |
+
console.warn('Aucune évaluation trouvée');
|
| 42 |
showWarningMessage('Aucune donnée d\'évaluation trouvée. Générer des données de test pour commencer.');
|
| 43 |
document.getElementById('helpSection').style.display = 'block';
|
| 44 |
} else {
|
| 45 |
document.getElementById('warningMessage').style.display = 'none';
|
| 46 |
}
|
| 47 |
|
| 48 |
+
// Charger les scénarios
|
| 49 |
+
return fetch('/api/scenarios')
|
| 50 |
+
.then(r => r.ok ? r.json() : fetch('scenarios.json').then(r2 => r2.json()))
|
| 51 |
+
.catch(() => fetch('scenarios.json').then(r => r.json()));
|
|
|
|
|
|
|
|
|
|
|
|
|
| 52 |
})
|
| 53 |
.then(data => {
|
| 54 |
scenariosData = data.scenarios || [];
|
| 55 |
+
console.log(`${scenariosData.length} scénarios chargés`);
|
|
|
|
|
|
|
|
|
|
|
|
|
| 56 |
|
| 57 |
+
// Charger les reviews
|
| 58 |
+
return fetch('/api/reviews')
|
| 59 |
+
.then(r => r.ok ? r.json() : fetch('review.json').then(r2 => r2.json()))
|
| 60 |
+
.catch(() => fetch('review.json').then(r => r.json()));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 61 |
})
|
| 62 |
.then(data => {
|
| 63 |
reviewsData = data.reviews || [];
|
| 64 |
+
console.log(`${reviewsData.length} reviews chargés`);
|
| 65 |
|
| 66 |
// Traiter les données
|
| 67 |
processEvaluations();
|
|
|
|
| 72 |
showErrorMessage(`Erreur de chargement: ${error.message}<br>
|
| 73 |
<br>
|
| 74 |
<strong>Solutions possibles :</strong><br>
|
| 75 |
+
1. Vérifiez que les fichiers JSON existent<br>
|
| 76 |
2. Générez des données de test avec le bouton ci-dessous<br>
|
| 77 |
3. Vérifiez la console du navigateur (F12) pour plus de détails<br>
|
| 78 |
<br>
|
|
|
|
| 94 |
|
| 95 |
showLoadingMessage('Génération des données de test...');
|
| 96 |
|
| 97 |
+
// Essayer d'abord l'API
|
| 98 |
fetch('/api/generate_test_data')
|
| 99 |
.then(response => {
|
| 100 |
if (!response.ok) {
|
| 101 |
+
// Si l'API n'est pas disponible, générer localement
|
| 102 |
+
return generateLocalTestData();
|
| 103 |
}
|
| 104 |
return response.json();
|
| 105 |
})
|
| 106 |
.then(data => {
|
| 107 |
console.log('Données de test générées:', data);
|
| 108 |
showSuccessMessage(`✅ Données de test générées avec succès !<br>
|
| 109 |
+
- ${data.evaluations || 5} évaluations<br>
|
| 110 |
+
- ${data.scenarios || scenariosData.length} scénarios<br>
|
| 111 |
+
- ${data.reviews || 3} reviews`);
|
| 112 |
|
| 113 |
// Recharger les données
|
| 114 |
setTimeout(() => {
|
|
|
|
| 117 |
})
|
| 118 |
.catch(error => {
|
| 119 |
console.error('Erreur génération données test:', error);
|
| 120 |
+
generateLocalTestData();
|
| 121 |
+
});
|
| 122 |
+
}
|
| 123 |
+
|
| 124 |
+
function generateLocalTestData() {
|
| 125 |
+
// Générer des évaluations de test
|
| 126 |
+
const testEvaluations = [];
|
| 127 |
+
const evaluators = ['Expert A', 'Expert B', 'Expert C', 'Anonyme'];
|
| 128 |
+
const roles = ['Professeur', 'Psychologue', 'Tuteur', 'Chercheur'];
|
| 129 |
+
|
| 130 |
+
for (let i = 0; i < 10; i++) {
|
| 131 |
+
const scenarioId = Math.floor(Math.random() * 16) + 1;
|
| 132 |
+
const evaluatorIndex = Math.floor(Math.random() * evaluators.length);
|
| 133 |
+
|
| 134 |
+
const metrics = {
|
| 135 |
+
AR: Math.floor(Math.random() * 6),
|
| 136 |
+
AE: Math.floor(Math.random() * 6),
|
| 137 |
+
ESR: Math.floor(Math.random() * 6),
|
| 138 |
+
SDM: Math.floor(Math.random() * 6),
|
| 139 |
+
SM: Math.floor(Math.random() * 6)
|
| 140 |
+
};
|
| 141 |
+
|
| 142 |
+
const totalScore = (metrics.AR + metrics.AE + metrics.ESR + metrics.SDM + metrics.SM) * 4;
|
| 143 |
+
|
| 144 |
+
testEvaluations.push({
|
| 145 |
+
id: `test_eval_${Date.now()}_${i}`,
|
| 146 |
+
scenario_id: scenarioId,
|
| 147 |
+
evaluator_name: evaluators[evaluatorIndex],
|
| 148 |
+
evaluator_role: roles[evaluatorIndex],
|
| 149 |
+
trust_metrics: metrics,
|
| 150 |
+
trust_score: totalScore,
|
| 151 |
+
comment: 'Évaluation générée automatiquement pour test',
|
| 152 |
+
timestamp: new Date(Date.now() - Math.random() * 10000000000).toISOString(),
|
| 153 |
+
cross_reading: Math.random() > 0.7
|
| 154 |
});
|
| 155 |
+
}
|
| 156 |
+
|
| 157 |
+
// Générer des reviews de test
|
| 158 |
+
const testReviews = [];
|
| 159 |
+
for (let i = 0; i < 5; i++) {
|
| 160 |
+
if (testEvaluations[i]) {
|
| 161 |
+
const decisions = ['approved', 'needs_revision', 'rejected'];
|
| 162 |
+
const decision = decisions[Math.floor(Math.random() * decisions.length)];
|
| 163 |
+
|
| 164 |
+
testReviews.push({
|
| 165 |
+
id: `test_review_${Date.now()}_${i}`,
|
| 166 |
+
evaluation_id: testEvaluations[i].id,
|
| 167 |
+
scenario_id: testEvaluations[i].scenario_id,
|
| 168 |
+
evaluator_name: testEvaluations[i].evaluator_name,
|
| 169 |
+
evaluator_role: testEvaluations[i].evaluator_role,
|
| 170 |
+
original_score: testEvaluations[i].trust_score,
|
| 171 |
+
original_comment: testEvaluations[i].comment,
|
| 172 |
+
decision: decision,
|
| 173 |
+
review_comment: `Review automatique - ${decision === 'approved' ? 'Approuvé' : decision === 'needs_revision' ? 'Nécessite révision' : 'Rejeté'}`,
|
| 174 |
+
reviewer: 'Système de test',
|
| 175 |
+
timestamp: new Date().toISOString()
|
| 176 |
+
});
|
| 177 |
+
}
|
| 178 |
+
}
|
| 179 |
+
|
| 180 |
+
// Sauvegarder localement
|
| 181 |
+
try {
|
| 182 |
+
// Ajouter aux évaluations existantes
|
| 183 |
+
allEvaluations = [...allEvaluations, ...testEvaluations];
|
| 184 |
+
|
| 185 |
+
// Ajouter aux reviews existants
|
| 186 |
+
reviewsData = [...reviewsData, ...testReviews];
|
| 187 |
+
|
| 188 |
+
// Mettre à jour l'affichage
|
| 189 |
+
processEvaluations();
|
| 190 |
+
filterAllEvaluations();
|
| 191 |
+
|
| 192 |
+
showSuccessMessage(`✅ Données de test générées localement !<br>
|
| 193 |
+
- ${testEvaluations.length} nouvelles évaluations<br>
|
| 194 |
+
- ${testReviews.length} nouveaux reviews`);
|
| 195 |
+
|
| 196 |
+
return {
|
| 197 |
+
evaluations: testEvaluations.length,
|
| 198 |
+
reviews: testReviews.length,
|
| 199 |
+
scenarios: scenariosData.length
|
| 200 |
+
};
|
| 201 |
+
} catch (error) {
|
| 202 |
+
console.error('Erreur génération locale:', error);
|
| 203 |
+
showErrorMessage('Erreur lors de la génération des données de test');
|
| 204 |
+
throw error;
|
| 205 |
+
}
|
| 206 |
}
|
| 207 |
|
| 208 |
// ================= TRAITEMENT DES DONNÉES =================
|
|
|
|
| 265 |
|
| 266 |
// Assurer un scénario ID
|
| 267 |
if (!eval.scenario_id && eval.scenario_id !== 0) {
|
| 268 |
+
eval.scenario_id = Math.floor(Math.random() * 16) + 1;
|
| 269 |
}
|
| 270 |
});
|
| 271 |
|
|
|
|
| 785 |
original_comment: evaluation.comment,
|
| 786 |
decision: decision,
|
| 787 |
review_comment: reviewComment,
|
| 788 |
+
reviewer: 'Expert Reviewer',
|
| 789 |
+
timestamp: new Date().toISOString()
|
| 790 |
};
|
| 791 |
|
| 792 |
// Envoyer au serveur via API
|
|
|
|
| 797 |
},
|
| 798 |
body: JSON.stringify(reviewData)
|
| 799 |
})
|
| 800 |
+
.then(response => {
|
| 801 |
+
// Vérifier si la réponse est en HTML (erreur) au lieu de JSON
|
| 802 |
+
const contentType = response.headers.get("content-type");
|
| 803 |
+
if (!contentType || !contentType.includes("application/json")) {
|
| 804 |
+
return response.text().then(text => {
|
| 805 |
+
throw new Error(`Le serveur a renvoyé du HTML au lieu du JSON. Vérifiez que l'API /api/save_review existe.`);
|
| 806 |
+
});
|
| 807 |
+
}
|
| 808 |
+
return response.json();
|
| 809 |
+
})
|
| 810 |
.then(data => {
|
| 811 |
if (data.status === 'ok') {
|
| 812 |
+
// Ajouter le review localement
|
| 813 |
+
const reviewId = `review_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
| 814 |
+
reviewsData.push({
|
| 815 |
+
id: reviewId,
|
| 816 |
+
...reviewData
|
| 817 |
+
});
|
| 818 |
+
|
| 819 |
+
// Mettre à jour l'affichage
|
| 820 |
+
filterAllEvaluations();
|
| 821 |
+
|
| 822 |
+
// Fermer la modale
|
| 823 |
+
closeReviewModal();
|
| 824 |
+
|
| 825 |
+
showSuccessMessage(`✅ Review sauvegardé avec succès ! (${reviewsData.length} reviews au total)`);
|
| 826 |
} else {
|
| 827 |
throw new Error(data.error || 'Erreur inconnue');
|
| 828 |
}
|
| 829 |
})
|
| 830 |
+
.catch(error => {
|
| 831 |
+
console.error('Erreur sauvegarde review:', error);
|
| 832 |
+
|
| 833 |
+
// Sauvegarde locale en cas d'erreur API
|
| 834 |
+
const reviewId = `review_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
| 835 |
+
const localReview = {
|
| 836 |
+
id: reviewId,
|
| 837 |
+
...reviewData
|
| 838 |
+
};
|
| 839 |
+
|
| 840 |
+
reviewsData.push(localReview);
|
| 841 |
|
| 842 |
// Mettre à jour l'affichage
|
| 843 |
filterAllEvaluations();
|
|
|
|
| 845 |
// Fermer la modale
|
| 846 |
closeReviewModal();
|
| 847 |
|
| 848 |
+
showSuccessMessage(`✅ Review sauvegardé localement (API non disponible). (${reviewsData.length} reviews)`);
|
| 849 |
+
|
| 850 |
+
// Afficher un avertissement
|
| 851 |
+
showWarningMessage(`Le review a été sauvegardé localement. Pour une sauvegarde permanente,
|
| 852 |
+
ajoutez l'endpoint /api/save_review à votre backend Flask.`);
|
| 853 |
});
|
| 854 |
}
|
| 855 |
|
|
|
|
| 1225 |
window.openReviewModal = openReviewModal;
|
| 1226 |
window.closeReviewModal = closeReviewModal;
|
| 1227 |
window.saveReview = saveReview;
|
| 1228 |
+
window.generateTestData = generateTestData;
|
| 1229 |
+
window.loadData = loadData;
|