feat: add domain
This commit is contained in:
@@ -155,14 +155,16 @@ def edit(id):
|
||||
'description': element.description or '',
|
||||
'skill': element.skill or '',
|
||||
'max_points': float(element.max_points),
|
||||
'grading_type': element.grading_type
|
||||
'grading_type': element.grading_type,
|
||||
'domain_id': element.domain_id
|
||||
}
|
||||
exercise_data['grading_elements'].append(element_data)
|
||||
exercises_data.append(exercise_data)
|
||||
|
||||
# Récupérer les compétences configurées
|
||||
# Récupérer les compétences et domaines configurées
|
||||
from app_config import config_manager
|
||||
competences = config_manager.get_competences_list()
|
||||
domains = config_manager.get_domains_list()
|
||||
|
||||
return render_template('assessment_form_unified.html',
|
||||
form=form,
|
||||
@@ -170,7 +172,8 @@ def edit(id):
|
||||
assessment=assessment,
|
||||
exercises_json=exercises_data,
|
||||
is_edit=True,
|
||||
competences=competences)
|
||||
competences=competences,
|
||||
domains=domains)
|
||||
|
||||
@bp.route('/new', methods=['GET', 'POST'])
|
||||
@handle_db_errors
|
||||
@@ -182,13 +185,15 @@ def new():
|
||||
if result:
|
||||
return result
|
||||
|
||||
# Récupérer les compétences configurées
|
||||
# Récupérer les compétences et domaines configurées
|
||||
competences = config_manager.get_competences_list()
|
||||
domains = config_manager.get_domains_list()
|
||||
|
||||
return render_template('assessment_form_unified.html',
|
||||
form=form,
|
||||
title='Nouvelle évaluation complète',
|
||||
competences=competences)
|
||||
competences=competences,
|
||||
domains=domains)
|
||||
|
||||
@bp.route('/<int:id>/results')
|
||||
@handle_db_errors
|
||||
|
||||
156
routes/domains.py
Normal file
156
routes/domains.py
Normal file
@@ -0,0 +1,156 @@
|
||||
from flask import Blueprint, jsonify, request, current_app
|
||||
from models import db, Domain
|
||||
from app_config import config_manager
|
||||
from utils import handle_db_errors
|
||||
|
||||
bp = Blueprint('domains', __name__, url_prefix='/api/domains')
|
||||
|
||||
@bp.route('/', methods=['GET'])
|
||||
@handle_db_errors
|
||||
def list_domains():
|
||||
"""Liste tous les domaines disponibles."""
|
||||
domains = config_manager.get_domains_list()
|
||||
return jsonify({'success': True, 'domains': domains})
|
||||
|
||||
|
||||
@bp.route('/', methods=['POST'])
|
||||
@handle_db_errors
|
||||
def create_domain():
|
||||
"""Crée un nouveau domaine dynamiquement."""
|
||||
data = request.get_json()
|
||||
|
||||
if not data or not data.get('name'):
|
||||
return jsonify({'success': False, 'error': 'Nom du domaine requis'}), 400
|
||||
|
||||
name = data['name'].strip()
|
||||
color = data.get('color', '#6B7280')
|
||||
description = data.get('description', '')
|
||||
|
||||
# Vérifier que le domaine n'existe pas déjà
|
||||
if Domain.query.filter_by(name=name).first():
|
||||
return jsonify({'success': False, 'error': 'Un domaine avec ce nom existe déjà'}), 400
|
||||
|
||||
success = config_manager.add_domain(name, color, description)
|
||||
|
||||
if success:
|
||||
# Récupérer le domaine créé
|
||||
domain = Domain.query.filter_by(name=name).first()
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'domain': {
|
||||
'id': domain.id,
|
||||
'name': domain.name,
|
||||
'color': domain.color,
|
||||
'description': domain.description or ''
|
||||
}
|
||||
})
|
||||
else:
|
||||
return jsonify({'success': False, 'error': 'Erreur lors de la création du domaine'}), 500
|
||||
|
||||
@bp.route('/search', methods=['GET'])
|
||||
@handle_db_errors
|
||||
def search_domains():
|
||||
"""Recherche des domaines avec autocomplétion avancée."""
|
||||
query = request.args.get('q', '').strip()
|
||||
|
||||
if not query or len(query) < 1:
|
||||
return jsonify({'success': True, 'domains': []})
|
||||
|
||||
# Utiliser la recherche directe en base pour plus d'efficacité
|
||||
domains_query = Domain.query.filter(
|
||||
Domain.name.ilike(f'%{query}%')
|
||||
).order_by(
|
||||
# Prioriser les correspondances exactes, puis celles qui commencent par la requête
|
||||
db.case(
|
||||
(Domain.name.ilike(query), 1),
|
||||
(Domain.name.ilike(f'{query}%'), 2),
|
||||
else_=3
|
||||
),
|
||||
Domain.name.asc()
|
||||
).limit(8)
|
||||
|
||||
domains = domains_query.all()
|
||||
|
||||
# Convertir en format JSON
|
||||
domains_data = [{
|
||||
'id': domain.id,
|
||||
'name': domain.name,
|
||||
'color': domain.color,
|
||||
'description': domain.description or ''
|
||||
} for domain in domains]
|
||||
|
||||
return jsonify({'success': True, 'domains': domains_data})
|
||||
|
||||
@bp.route('/<int:domain_id>', methods=['PUT'])
|
||||
@handle_db_errors
|
||||
def update_domain(domain_id):
|
||||
"""Met à jour un domaine existant."""
|
||||
data = request.get_json()
|
||||
domain = Domain.query.get_or_404(domain_id)
|
||||
|
||||
if data.get('name'):
|
||||
domain.name = data['name'].strip()
|
||||
if data.get('color'):
|
||||
domain.color = data['color']
|
||||
if 'description' in data:
|
||||
domain.description = data['description']
|
||||
|
||||
try:
|
||||
db.session.commit()
|
||||
return jsonify({'success': True})
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
current_app.logger.error(f"Erreur lors de la mise à jour du domaine: {e}")
|
||||
return jsonify({'success': False, 'error': 'Erreur lors de la sauvegarde'}), 500
|
||||
|
||||
@bp.route('/<int:domain_id>', methods=['DELETE'])
|
||||
@handle_db_errors
|
||||
def delete_domain(domain_id):
|
||||
"""Supprime un domaine (si non utilisé)."""
|
||||
domain = Domain.query.get_or_404(domain_id)
|
||||
|
||||
# Vérifier que le domaine n'est pas utilisé
|
||||
if domain.grading_elements:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': f'Ce domaine est utilisé par {len(domain.grading_elements)} éléments de notation'
|
||||
}), 400
|
||||
|
||||
try:
|
||||
db.session.delete(domain)
|
||||
db.session.commit()
|
||||
return jsonify({'success': True})
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
current_app.logger.error(f"Erreur lors de la suppression du domaine: {e}")
|
||||
return jsonify({'success': False, 'error': 'Erreur lors de la suppression'}), 500
|
||||
|
||||
@bp.route('/<int:domain_id>/usage', methods=['GET'])
|
||||
@handle_db_errors
|
||||
def domain_usage(domain_id):
|
||||
"""Récupère les informations d'utilisation d'un domaine."""
|
||||
domain = Domain.query.get_or_404(domain_id)
|
||||
|
||||
# Compter les éléments de notation utilisant ce domaine
|
||||
elements_count = len(domain.grading_elements)
|
||||
|
||||
# Récupérer les évaluations concernées
|
||||
assessments = set()
|
||||
for element in domain.grading_elements:
|
||||
assessments.add(element.exercise.assessment)
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'usage': {
|
||||
'elements_count': elements_count,
|
||||
'assessments_count': len(assessments),
|
||||
'assessments': [
|
||||
{
|
||||
'id': assessment.id,
|
||||
'title': assessment.title,
|
||||
'class_name': assessment.class_group.name
|
||||
}
|
||||
for assessment in assessments
|
||||
]
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user