""" 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