feat: improve fullscreen mode

This commit is contained in:
2025-08-06 14:26:13 +02:00
parent 72c7ab9a03
commit 25945fc64c
2 changed files with 817 additions and 988 deletions

View File

@@ -1,4 +1,4 @@
from flask import Blueprint, render_template, redirect, url_for, flash, request from flask import Blueprint, render_template, redirect, url_for, flash, request, jsonify
from models import db, Assessment, Student, Grade, GradingElement, Exercise from models import db, Assessment, Student, Grade, GradingElement, Exercise
from app_config import config_manager from app_config import config_manager
@@ -35,66 +35,98 @@ def assessment_grading(assessment_id):
@bp.route('/assessments/<int:assessment_id>/grading/save', methods=['POST']) @bp.route('/assessments/<int:assessment_id>/grading/save', methods=['POST'])
def save_grades(assessment_id): def save_grades(assessment_id):
assessment = Assessment.query.get_or_404(assessment_id) assessment = Assessment.query.get_or_404(assessment_id)
errors = []
for key, value in request.form.items(): try:
if key.startswith('grade_'): for key, value in request.form.items():
# Parse key: grade_<student_id>_<element_id> if key.startswith('grade_'):
parts = key.split('_') # Parse key: grade_<student_id>_<element_id>
if len(parts) == 3: parts = key.split('_')
student_id = int(parts[1]) if len(parts) == 3:
element_id = int(parts[2]) student_id = int(parts[1])
element_id = int(parts[2])
# Find or create grade
grade = Grade.query.filter_by( # Find or create grade
student_id=student_id, grade = Grade.query.filter_by(
grading_element_id=element_id student_id=student_id,
).first() grading_element_id=element_id
).first()
if value.strip(): # If value is not empty
# Validation unifiée selon le nouveau système if value.strip(): # If value is not empty
grading_element = GradingElement.query.get(element_id) # Validation unifiée selon le nouveau système
if grading_element: grading_element = GradingElement.query.get(element_id)
# Passer max_points pour la validation des notes if grading_element:
max_points = grading_element.max_points if grading_element.grading_type == 'notes' else None # Passer max_points pour la validation des notes
max_points = grading_element.max_points if grading_element.grading_type == 'notes' else None
# Normaliser virgule en point pour les notes avant sauvegarde
normalized_value = value.strip() # Normaliser virgule en point pour les notes avant sauvegarde
if grading_element.grading_type == 'notes' and ',' in normalized_value: normalized_value = value.strip()
normalized_value = normalized_value.replace(',', '.') if grading_element.grading_type == 'notes' and ',' in normalized_value:
normalized_value = normalized_value.replace(',', '.')
if config_manager.validate_grade_value(normalized_value, grading_element.grading_type, max_points):
if not grade: if config_manager.validate_grade_value(normalized_value, grading_element.grading_type, max_points):
grade = Grade( if not grade:
student_id=student_id, grade = Grade(
grading_element_id=element_id, student_id=student_id,
value=normalized_value grading_element_id=element_id,
) value=normalized_value
db.session.add(grade) )
db.session.add(grade)
else:
grade.value = normalized_value
else: else:
grade.value = normalized_value errors.append(f'Valeur invalide pour {grading_element.label if grading_element else "cet élément"}: {value}')
else: else:
flash(f'Valeur invalide pour {grading_element.label if grading_element else "cet élément"}: {value}', 'warning') errors.append(f'Élément de notation non trouvé: {element_id}')
else: elif grade: # If value is empty but grade exists, delete it
flash(f'Élément de notation non trouvé: {element_id}', 'error') db.session.delete(grade)
elif grade: # If value is empty but grade exists, delete it
db.session.delete(grade) # Handle comments
for key, value in request.form.items():
# Handle comments if key.startswith('comment_'):
for key, value in request.form.items(): parts = key.split('_')
if key.startswith('comment_'): if len(parts) == 3:
parts = key.split('_') student_id = int(parts[1])
if len(parts) == 3: element_id = int(parts[2])
student_id = int(parts[1])
element_id = int(parts[2]) grade = Grade.query.filter_by(
student_id=student_id,
grade = Grade.query.filter_by( grading_element_id=element_id
student_id=student_id, ).first()
grading_element_id=element_id
).first() if grade:
grade.comment = value.strip() if value.strip() else None
if grade:
grade.comment = value.strip() if value.strip() else None db.session.commit()
db.session.commit() # Check if it's an AJAX request
flash('Notes sauvegardées avec succès !', 'success') if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
return redirect(url_for('grading.assessment_grading', assessment_id=assessment_id)) if errors:
return jsonify({
'success': False,
'message': 'Certaines notes n\'ont pas pu être sauvegardées',
'errors': errors
})
else:
return jsonify({
'success': True,
'message': 'Notes sauvegardées avec succès !'
})
else:
# Traditional form submission
if errors:
for error in errors:
flash(error, 'warning')
flash('Notes sauvegardées avec succès !', 'success')
return redirect(url_for('grading.assessment_grading', assessment_id=assessment_id))
except Exception as e:
db.session.rollback()
if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
return jsonify({
'success': False,
'message': f'Erreur lors de la sauvegarde: {str(e)}'
}), 500
else:
flash(f'Erreur lors de la sauvegarde: {str(e)}', 'error')
return redirect(url_for('grading.assessment_grading', assessment_id=assessment_id))

File diff suppressed because it is too large Load Diff