Améliorations

This commit is contained in:
Fabrication du Numérique 2025-06-03 12:52:33 +02:00
parent 69272a44d6
commit 255361e9aa
5 changed files with 94 additions and 45 deletions

View File

@ -567,6 +567,8 @@ def build_minerai_sections(md: str) -> str:
md,
flags=re.DOTALL
)
# suppression pour le dernier minerai dans la fiche IHH
md = re.sub(r"# Tableaux de synthèse.*<!---- AUTO-END:SECTION-IHH-TRAITEMENT -->", "", md, flags=re.DOTALL)
except Exception as e:
st.error(f"Erreur lors de la génération des sections IHH: {e}")

View File

@ -173,7 +173,7 @@ def interface_ia_nalyse(G_temp):
if liens_chemins:
G_final = exporter_graphe_filtre(G_temp, liens_chemins)
if st.button(str(_("pages.ia_nalyse.submit_request"))):
if st.button(str(_("pages.ia_nalyse.submit_request")), icon=":material/send:"):
soumettre_batch(st.session_state.username, G_final)
st.rerun()
else:
@ -181,15 +181,15 @@ def interface_ia_nalyse(G_temp):
elif resultat["statut"] == "terminé" and resultat["telechargement"]:
if not st.session_state.get("telechargement_confirme"):
st.download_button(str(_("buttons.download")), resultat["telechargement"], file_name="analyse.zip")
if st.button(str(_("pages.ia_nalyse.confirm_download"))):
st.download_button(str(_("buttons.download")), resultat["telechargement"], file_name="analyse.zip", icon=":material/download:")
if st.button(str(_("pages.ia_nalyse.confirm_download")), icon=":material/task_alt:"):
nettoyage_post_telechargement(st.session_state.username)
st.session_state["telechargement_confirme"] = True
st.rerun()
else:
st.success("Résultat supprimé. Vous pouvez relancer une nouvelle analyse.")
if st.button(str(_("buttons.refresh"))):
if st.button(str(_("buttons.refresh")), icon=":material/refresh:"):
st.rerun()
else:
if st.button(str(_("buttons.refresh"))):
if st.button(str(_("buttons.refresh")), icon=":material/refresh:"):
st.rerun()

View File

@ -8,6 +8,7 @@ suivant la structure définie dans Remarques.md.
import streamlit as st
import networkx as nx
import uuid
import re
from utils.translations import _
from utils.widgets import html_expander
from networkx.drawing.nx_agraph import write_dot
@ -169,6 +170,24 @@ def extraire_liens_filtres(chemins, niveaux, niveau_depart, niveau_arrivee, nive
liens.add((u, v))
return liens
CORRESPONDANCE_COULEURS = {
"Rouge": "red",
"Orange": "orange",
"Vert": "green",
"FAIBLE": "green",
"MODÉRÉE": "orange",
"ÉLEVÉE à CRITIQUE": "red"
}
def remplacer_par_badge(markdown_text, correspondance=CORRESPONDANCE_COULEURS):
# Échappe les mots à remplacer s'ils contiennent des accents ou espaces
for mot, couleur in correspondance.items():
# Utilise des bords de mots (\b) pour éviter les remplacements partiels
pattern = r'\b' + re.escape(mot) + r'\b'
remplacement = f":{couleur}-badge[{mot}]"
markdown_text = re.sub(pattern, remplacement, markdown_text)
return markdown_text
def interface_plan_d_action(G_temp):
st.markdown(f"# {str(_('pages.plan_d_action.title'))}")
@ -208,7 +227,7 @@ def interface_plan_d_action(G_temp):
G_final = exporter_graphe_filtre(G_temp, liens_chemins)
st.session_state["G_final"] = G_final
# formulaire ou sélection
if st.button(str(_("pages.plan_d_action.submit_request")), icon=":material/play_arrow:"):
if st.button(str(_("pages.plan_d_action.submit_request")), icon=":material/send:"):
# On déclenche la suite — mais on NE traite rien maintenant
st.session_state["plan_d_action"] = 1
st.rerun() # force la réexécution immédiatement avec état mis à jour
@ -223,7 +242,7 @@ def interface_plan_d_action(G_temp):
data = extract_data_from_graph(graph, ref_graph)
results = calculate_vulnerabilities(data, config)
report, file_names = generate_report(data, results, config)
write_report(report, st.session_state["G_md"])
write_report(remplacer_par_badge(report), st.session_state["G_md"])
st.session_state["g_md_done"] = True # pour ne pas re-traiter à chaque affichage
# Affichage de linterface Streamlit

View File

@ -365,6 +365,8 @@ def afficher_bloc_ihh_isg(titre, ihh, isg, details_content=""):
# 1. Afficher vulnérabilité combinée en premier
if "#### Vulnérabilité combinée IHH-ISG" in details_content:
conteneur, = st.columns([1], gap="small", border=True)
with conteneur:
st.markdown("#### Vulnérabilité combinée IHH-ISG")
afficher_section_texte(lines, "#### Vulnérabilité combinée IHH-ISG", "###")
@ -442,6 +444,8 @@ def afficher_section_texte(lines, section_start, section_end_marker=None):
def afficher_description(titre, description):
st.markdown(f"## {titre}")
conteneur, = st.columns([1], gap="small", border=True)
with conteneur:
if description:
lines = description.split('\n')
description_lines = []
@ -480,6 +484,8 @@ def afficher_caracteristiques_minerai(minerai, mineraux_data, details_content=""
# 3. Afficher la vulnérabilité combinée ICS-IVC en dernier
if "#### Vulnérabilité combinée ICS-IVC" in details_content:
conteneur, = st.columns([1], gap="small", border=True)
with conteneur:
st.markdown("#### Vulnérabilité combinée ICS-IVC")
afficher_section_texte(lines, "#### Vulnérabilité combinée ICS-IVC", "####")
@ -558,11 +564,12 @@ def set_vulnerability(v1, v2, t1, t2, seuils):
return poids, couleur, v1_couleur, v2_couleur
def colorer_couleurs(la_couleur):
if la_couleur.lower() == "rouge":
t = la_couleur.lower()
if t == "rouge" or t == "difficile":
return f":red-badge[{la_couleur}]"
if la_couleur.lower() == "orange":
if t == "orange" or t == "modérée":
return f":orange-badge[{la_couleur}]"
if la_couleur.lower() == "vert":
if t == "vert" or t == "facile":
return f":green-badge[{la_couleur}]"
return la_couleur
@ -721,7 +728,7 @@ def initialiser_interface(filepath: str, config_path: str = "assets/config.yaml"
* pondération de la Substitution dans le calcul de la criticité globale : 2
""")
st.markdown("---")
st.markdown("## Préconisations et indicateurs")
with st.expander("Préconisations et indicateurs génériques"):
col_left, col_right = st.columns([1, 1], gap="small", border=True)
@ -730,7 +737,7 @@ def initialiser_interface(filepath: str, config_path: str = "assets/config.yaml"
st.markdown("Mise en œuvre : \n")
for niveau, contenu in PRECONISATIONS.items():
if niveau in niveau_criticite:
contenu_md = f"* {niveau}\n"
contenu_md = f"* {colorer_couleurs(niveau)}\n"
for p in PRECONISATIONS[niveau]:
contenu_md += f" - {p}\n"
st.markdown(contenu_md)
@ -739,7 +746,7 @@ def initialiser_interface(filepath: str, config_path: str = "assets/config.yaml"
st.markdown("Mise en œuvre : \n")
for niveau, contenu in INDICATEURS.items():
if niveau in niveau_criticite:
contenu_md = f"* {niveau}\n"
contenu_md = f"* {colorer_couleurs(niveau)}\n"
for p in INDICATEURS[niveau]:
contenu_md += f" - {p}\n"
st.markdown(contenu_md)
@ -760,15 +767,21 @@ def initialiser_interface(filepath: str, config_path: str = "assets/config.yaml"
niveau_criticite_operation["Extraction"] = affectation_poids(poids_E)
for operation in ["Assemblage", "Fabrication", "Traitement", "Extraction"]:
if operation == "Assemblage":
item = sel_prod
elif operation == "Fabrication":
item = sel_comp
else:
item = sel_miner
with st.expander(f"Préconisations et indicateurs spécifiques - {operation}"):
st.markdown(f"### {operation}")
st.markdown(f"### {operation} -> :blue-background[{item}]")
col_left, col_right = st.columns([1, 1], gap="small", border=True)
with col_left:
st.markdown("#### Préconisations :\n\n")
st.markdown("Mise en œuvre : \n")
for niveau, contenu in PRECONISATIONS[operation].items():
if niveau in niveau_criticite_operation[operation]:
contenu_md = f"* {niveau}\n"
contenu_md = f"* {colorer_couleurs(niveau)}\n"
for p in PRECONISATIONS[operation][niveau]:
contenu_md += f" - {p}\n"
st.markdown(contenu_md)
@ -777,12 +790,12 @@ def initialiser_interface(filepath: str, config_path: str = "assets/config.yaml"
st.markdown("Mise en œuvre : \n")
for niveau, contenu in INDICATEURS[operation].items():
if niveau in niveau_criticite_operation[operation]:
contenu_md = f"* {niveau}\n"
contenu_md = f"* {colorer_couleurs(niveau)}\n"
for p in INDICATEURS[operation][niveau]:
contenu_md += f" - {p}\n"
st.markdown(contenu_md)
st.markdown("---")
st.markdown("## Détails des opérations")
with st.expander(f"{sel_prod} et Assemblage"):
assemblage_details = details_sections.get(f"{sel_prod}_assemblage", "")
@ -802,9 +815,7 @@ def initialiser_interface(filepath: str, config_path: str = "assets/config.yaml"
extraction_details = details_sections.get(f"{sel_miner}_extraction", "")
afficher_bloc_ihh_isg("Extraction", mineraux[sel_miner]["IHH_Extraction"], mineraux[sel_miner]["ISG_Extraction"], extraction_details)
traitement_details = details_sections.get(f"{sel_miner}_traitement", "")
traitement_details = details_sections.get(f"{sel_miner}_traitement", "").removesuffix("\n---\n")
afficher_bloc_ihh_isg("Traitement", mineraux[sel_miner]["IHH_Traitement"], mineraux[sel_miner]["ISG_Traitement"], traitement_details)
afficher_caracteristiques_minerai(sel_miner, mineraux[sel_miner], minerai_general)
st.markdown("---")

View File

@ -137,6 +137,7 @@ ASUS_Taiwan_Assemblage_OrdiBureau [fillcolor="#d1e0ff", label=ASUS, niveau=12];
HP_Chine_Assemblage_OrdiBureau [fillcolor="#d1e0ff", label="HP China", niveau=12];
Lenovo_Chine_Assemblage_OrdiBureau [fillcolor="#d1e0ff", label=Lenovo, niveau=12];
OrdiPortable [fillcolor="#a0d6ff", label="Ordinateur portable", niveau=0];
StationTravailPortable [fillcolor="#a0d6ff", label="Station de travail portable", niveau=0];
Assemblage_OrdiPortable [fillcolor="#ffd699", ihh_acteurs=14, ihh_pays=35, label=Assemblage, niveau=10];
Bresil_Assemblage_OrdiPortable [fillcolor="#e6f2ff", label=Brésil, niveau=11];
Chine_Assemblage_OrdiPortable [fillcolor="#e6f2ff", label=Chine, niveau=11];
@ -2476,6 +2477,22 @@ OrdiPortable -> SSDM2;
OrdiPortable -> ProcesseurX86;
OrdiPortable -> SSD25;
OrdiPortable -> Assemblage_OrdiPortable;
StationTravailPortable -> Audio;
StationTravailPortable -> Camera;
StationTravailPortable -> Capteurs;
StationTravailPortable -> Connecteurs;
StationTravailPortable -> EcranOLED;
StationTravailPortable -> Boitier;
StationTravailPortable -> Connectivite;
StationTravailPortable -> Batterie;
StationTravailPortable -> MemoireRAM;
StationTravailPortable -> CarteMere;
StationTravailPortable -> ProcesseurARM;
StationTravailPortable -> SSD25;
StationTravailPortable -> Television;
StationTravailPortable -> Assemblage_OrdiPortable;
Assemblage_OrdiPortable -> Bresil_Assemblage_OrdiPortable [color=purple, fontcolor=purple, label="3%", poids=1];
Assemblage_OrdiPortable -> Chine_Assemblage_OrdiPortable [color=purple, fontcolor=purple, label="56%", poids=2];
Assemblage_OrdiPortable -> Vietnam_Assemblage_OrdiPortable [color=purple, fontcolor=purple, label="11%", poids=1];