"""
UI Components
"""
import streamlit as st
def render_navigation(current_index, total_items):
"""
Affiche les boutons de navigation
Returns:
Nouvelle valeur de l'index si changement, None sinon
"""
col1, col2, col3 = st.columns([1, 2, 1])
new_index = None
with col1:
if st.button("Précédent", use_container_width=True, disabled=current_index == 0):
new_index = current_index - 1
with col2:
st.markdown(f"
Exemple {current_index + 1} / {total_items}
", unsafe_allow_html=True)
with col3:
if st.button("Suivant", use_container_width=True, disabled=current_index >= total_items - 1):
new_index = current_index + 1
return new_index
def render_code_block(code_text, language="python"):
"""Affiche un bloc de code avec syntax highlighting"""
st.markdown("### Code")
st.code(code_text, language=language)
def render_feedback_block(feedback_text):
"""Affiche le feedback dans un bloc stylisé adapté au thème"""
st.markdown("### Feedback")
# Utilise la classe CSS qui s'adapte automatiquement au thème
st.markdown(f"""
{feedback_text}
""", unsafe_allow_html=True)
def render_score_slider(score_key, current_score=3):
"""
Affiche le slider de notation
Returns:
Score sélectionné
"""
st.markdown("### Notez le feedback")
st.caption("À quel point ce feedback est-il utile et pertinent pour ce code ?")
score = st.slider(
"Score",
min_value=0,
max_value=5,
value=current_score,
step=1,
format="%d",
key=score_key,
help="0 = Pas utile du tout, 5 = Extrêmement utile"
)
# Show score meaning
score_meanings = {
0: "Pas utile / Incorrect",
1: "Très peu utile",
2: "Peu utile",
3: "Moyennement utile",
4: "Utile",
5: "Extrêmement utile"
}
st.info(f"{score} - {score_meanings[score]}")
return score
def render_comment_field(comment_key, current_comment=""):
"""
Affiche le champ de commentaire optionnel
Returns:
Commentaire saisi
"""
with st.expander("Ajouter un commentaire (optionnel)"):
comment = st.text_area(
"Commentaire",
value=current_comment,
key=comment_key,
placeholder="Pourquoi ce score ? (optionnel)",
label_visibility="collapsed"
)
return comment
def render_progress_metrics(total, scored, remaining, progress_pct):
"""Affiche les métriques de progression"""
st.markdown("### Progression")
col1, col2, col3, col4 = st.columns(4)
with col1:
st.metric("Total", total)
with col2:
st.metric("Scorés", scored)
with col3:
st.metric("Restants", remaining)
with col4:
st.metric("Progression", f"{progress_pct:.0f}%")
st.progress(progress_pct / 100)
def render_statistics(avg_score, most_common_score, score_counts):
"""Affiche les statistiques détaillées"""
st.markdown("### Statistiques des Scores")
col1, col2 = st.columns(2)
with col1:
st.metric("Score Moyen", f"{avg_score:.2f}")
with col2:
st.metric("Score le plus fréquent", f"{most_common_score[0]} ({most_common_score[1]}x)")
st.bar_chart(score_counts, height=200)
def render_export_section(export_data):
"""Affiche la section d'export"""
st.markdown("### Export")
col1, col2 = st.columns(2)
with col1:
st.metric("Items à exporter", len(export_data))
return col1, col2
def render_quick_actions(items_with_positive, feedback_scores, current_index):
"""
Affiche les actions rapides
Returns:
Tuple (reset_requested, jump_to_unscored, jump_to_index)
"""
st.markdown("### Actions Rapides")
col1, col2, col3 = st.columns(3)
reset_requested = False
jump_to_unscored = False
jump_to_index = None
with col1:
if st.button("Réinitialiser tous les scores", use_container_width=True):
reset_requested = True
with col2:
unscored_indices = [idx for idx, _ in items_with_positive if idx not in feedback_scores]
if unscored_indices and st.button("Aller au prochain non-scoré", use_container_width=True):
jump_to_unscored = True
with col3:
jump_to = st.number_input(
"Aller à l'exemple",
min_value=1,
max_value=len(items_with_positive),
value=current_index + 1,
step=1,
key="jump_to"
)
if st.button("Aller", use_container_width=True):
jump_to_index = jump_to - 1
return reset_requested, jump_to_unscored, jump_to_index