diff --git a/app/fiches/interface.py b/app/fiches/interface.py
index aeaf6b2..7e9d8fb 100644
--- a/app/fiches/interface.py
+++ b/app/fiches/interface.py
@@ -2,6 +2,7 @@
import streamlit as st
import requests
import os
+import pathlib
from .utils.tickets.display import afficher_tickets_par_fiche
from .utils.tickets.creation import formulaire_creation_ticket_dynamique
@@ -64,7 +65,8 @@ def interface_fiches():
else:
SEUILS = st.session_state["seuils"]
- html_path = os.path.join("HTML", dossier_choisi, os.path.splitext(fiche_choisie)[0] + ".html")
+ nom_fiche = os.path.splitext(fiche_choisie)[0]
+ html_path = os.path.join("HTML", dossier_choisi, nom_fiche + ".html")
path_relative = f"Documents/{dossier_choisi}/{fiche_choisie}"
commits_url = f"{GITEA_URL}/repos/{ORGANISATION}/{DEPOT_FICHES}/commits?path={path_relative}&sha={ENV}"
@@ -82,7 +84,24 @@ def interface_fiches():
with open(html_path, "r", encoding="utf-8") as f:
st.markdown(f.read(), unsafe_allow_html=True)
- st.markdown("
", unsafe_allow_html=True)
+ if st.session_state.get("logged_in", False):
+ pdf_name = nom_fiche + ".pdf"
+ pdf_path = os.path.join("static", "Fiches", dossier_choisi, pdf_name)
+
+ # Bouton de téléchargement du PDF
+ if os.path.exists(pdf_path):
+ with open(pdf_path, "rb") as pdf_file:
+ st.download_button(
+ label="Télécharger cette fiche en PDF",
+ data=pdf_file,
+ file_name=pdf_name,
+ mime="application/pdf",
+ help="Télécharger la version PDF de cette fiche",
+ key="telecharger_fiche_pdf"
+ )
+ else:
+ st.warning("Le fichier PDF de cette fiche n'est pas disponible.")
+
st.markdown("## Gestion des tickets pour cette fiche")
afficher_tickets_par_fiche(rechercher_tickets_gitea(fiche_choisie))
formulaire_creation_ticket_dynamique(fiche_choisie)
diff --git a/app/fiches/utils/dynamic/assemblage_fabrication/production.py b/app/fiches/utils/dynamic/assemblage_fabrication/production.py
index 6568e9f..d99dbca 100644
--- a/app/fiches/utils/dynamic/assemblage_fabrication/production.py
+++ b/app/fiches/utils/dynamic/assemblage_fabrication/production.py
@@ -23,7 +23,10 @@ def build_production_sections(md: str) -> str:
yaml_block = re.search(r"```yaml\n(.+?)\n```", md, re.DOTALL)
if not yaml_block:
return md
-
+
+ # Capture le bloc YAML complet pour le supprimer plus tard
+ yaml_block_full = yaml_block.group(0)
+
try:
yaml_data = yaml.safe_load(yaml_block.group(1))
except Exception as e:
@@ -130,5 +133,8 @@ def build_production_sections(md: str) -> str:
st.warning(f"Aucune section IHH trouvée pour le schéma {schema} dans la fiche technique IHH.")
except Exception as e:
st.error(f"Erreur lors de la lecture/traitement de la fiche IHH: {e}")
+
+ # Supprimer le bloc YAML du markdown final
+ md_modifie = md_modifie.replace(yaml_block_full, "")
return md_modifie
diff --git a/app/fiches/utils/tickets/core.py b/app/fiches/utils/tickets/core.py
index 8d4a9d3..99a88e5 100644
--- a/app/fiches/utils/tickets/core.py
+++ b/app/fiches/utils/tickets/core.py
@@ -64,7 +64,7 @@ def rechercher_tickets_gitea(fiche_selectionnee):
if not cible:
return []
- labels_cibles = set(cible["operations"] + [cible["item"]])
+ labels_cibles = set([cible["item"]])
tickets_associes = []
for issue in issues:
diff --git a/app/personnalisation/interface.py b/app/personnalisation/interface.py
index 2993cb9..53480fb 100644
--- a/app/personnalisation/interface.py
+++ b/app/personnalisation/interface.py
@@ -9,7 +9,7 @@ def interface_personnalisation(G):
st.markdown("# Personnalisation des produits finaux")
with st.expander("Comment utiliser cet onglet ?", expanded=False):
st.markdown("""
- 1. Cliquez sur "Ajouter un produit final" pour créer un nouveau produit
+ 1. Cliquez sur « Ajouter un produit final » pour créer un nouveau produit
2. Donnez un nom à votre produit
3. Sélectionnez une opération d'assemblage appropriée (si pertinent)
4. Choisissez les composants qui constituent votre produit dans la liste proposée
diff --git a/assets/fiches_labels.csv b/assets/fiches_labels.csv
index 5917b8c..e74ea37 100644
--- a/assets/fiches_labels.csv
+++ b/assets/fiches_labels.csv
@@ -36,15 +36,15 @@ Fiche minerai aluminium.md,Extraction/Traitement/Réserves,Aluminium
Fiche minerai antimoine.md,Extraction/Traitement/Réserves,Antimoine
Fiche minerai argent.md,Extraction/Traitement/Réserves,Argent
Fiche minerai arsenic.md,Extraction/Traitement/Réserves,Arsenic
-Fiche minerai beryllium.md,Extraction/Traitement/Réserves,Beryllium
-Fiche minerai ceramiques.md,Extraction/Traitement/Réserves,Ceramiques
-Fiche minerai cerium.md,Extraction/Traitement/Réserves,Cerium
+Fiche minerai béryllium.md,Extraction/Traitement/Réserves,Beryllium
+Fiche minerai céramiques.md,Extraction/Traitement/Réserves,Ceramiques
+Fiche minerai cérium.md,Extraction/Traitement/Réserves,Cerium
Fiche minerai chrome.md,Extraction/Traitement/Réserves,Chrome
Fiche minerai cobalt.md,Extraction/Traitement/Réserves,Cobalt
Fiche minerai cuivre.md,Extraction/Traitement/Réserves,Cuivre
Fiche minerai dysprosium.md,Extraction/Traitement/Réserves,Dysprosium
Fiche minerai erbium.md,Extraction/Traitement/Réserves,Erbium
-Fiche minerai etain.md,Extraction/Traitement/Réserves,Etain
+Fiche minerai étain.md,Extraction/Traitement/Réserves,Etain
Fiche minerai europium.md,Extraction/Traitement/Réserves,Europium
Fiche minerai fluorite.md,Extraction/Traitement/Réserves,Fluorite
Fiche minerai gadolinium.md,Extraction/Traitement/Réserves,Gadolinium
@@ -56,9 +56,9 @@ Fiche minerai holmium.md,Extraction/Traitement/Réserves,Holmium
Fiche minerai indiumetain.md,Extraction/Traitement/Réserves,IndiumEtain
Fiche minerai lanthane.md,Extraction/Traitement/Réserves,Lanthane
Fiche minerai lithium.md,Extraction/Traitement/Réserves,Lithium
-Fiche minerai magnesium.md,Extraction/Traitement/Réserves,Magnesium
-Fiche minerai manganese.md,Extraction/Traitement/Réserves,Manganese
-Fiche minerai neodyme.md,Extraction/Traitement/Réserves,Neodyme
+Fiche minerai magnésium.md,Extraction/Traitement/Réserves,Magnesium
+Fiche minerai manganèse.md,Extraction/Traitement/Réserves,Manganese
+Fiche minerai néodyme.md,Extraction/Traitement/Réserves,Neodyme
Fiche minerai nickel.md,Extraction/Traitement/Réserves,Nickel
Fiche minerai or.md,Extraction/Traitement/Réserves,Or
Fiche minerai palladium.md,Extraction/Traitement/Réserves,Palladium
@@ -67,8 +67,8 @@ Fiche minerai phosphore.md,Extraction/Traitement/Réserves,Phosphore
Fiche minerai plastiques.md,Extraction/Traitement/Réserves,Plastiques
Fiche minerai platine.md,Extraction/Traitement/Réserves,Platine
Fiche minerai plomb.md,Extraction/Traitement/Réserves,Plomb
-Fiche minerai polystyrene.md,Extraction/Traitement/Réserves,Polystyrene
-Fiche minerai praseodyme.md,Extraction/Traitement/Réserves,Praseodyme
+Fiche minerai polystyrène.md,Extraction/Traitement/Réserves,Polystyrene
+Fiche minerai praséodyme.md,Extraction/Traitement/Réserves,Praseodyme
Fiche minerai pvc.md,Extraction/Traitement/Réserves,PVC
Fiche minerai quartz.md,Extraction/Traitement/Réserves,Quartz
Fiche minerai samarium.md,Extraction/Traitement/Réserves,Samarium
@@ -77,7 +77,7 @@ Fiche minerai silicium.md,Extraction/Traitement/Réserves,Silicium
Fiche minerai tantale.md,Extraction/Traitement/Réserves,Tantale
Fiche minerai terbium.md,Extraction/Traitement/Réserves,Terbium
Fiche minerai titane.md,Extraction/Traitement/Réserves,Titane
-Fiche minerai tungstene.md,Extraction/Traitement/Réserves,Tungstene
+Fiche minerai tungstène.md,Extraction/Traitement/Réserves,Tungstene
Fiche minerai verre.md,Extraction/Traitement/Réserves,Verre
Fiche minerai yttrium.md,Extraction/Traitement/Réserves,Yttrium
Fiche minerai zinc.md,Extraction/Traitement/Réserves,Zinc
diff --git a/assets/styles/base.css b/assets/styles/base.css
index 92b4b22..ac9aa78 100644
--- a/assets/styles/base.css
+++ b/assets/styles/base.css
@@ -1,185 +1,60 @@
/* --- Base.css --- */
+/* ==========================================
+ 1. Reset et base
+ ========================================== */
.stAppHeader {
visibility: hidden;
}
-/* Conteneur principal */
-.block-container {
- max-width: 1024px !important;
- padding-left: 2rem;
- padding-right: 2rem;
- padding: 0rem 1rem 10rem;
+body, html {
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}
-.stVerticalBlock {
- gap: 0.5rem !important;
+body, .stApp, .block-container {
+ background-color: var(--bg-color) !important;
+ color: var(--text-color) !important;
}
-/* Typographie & structure */
-body,
-html {
- font-family:
- -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial,
- sans-serif;
-}
+/* ==========================================
+ 2. Layout et containers
+ ========================================== */
.block-container {
max-width: 1024px !important;
padding: 0 1rem 10rem;
}
+
.stVerticalBlock {
gap: 0.5rem !important;
}
-/* Boutons & sliders */
+/* ==========================================
+ 3. Composants d'interface
+ ========================================== */
+
+/* --- 3.1 Boutons --- */
.stButton > button,
.stDownloadButton > button,
+.stFormSubmitButton > button,
.stSlider > div > div {
background-color: darkgreen !important;
color: white !important;
border: 1px solid grey;
}
-/* Sidebar (style fixe) */
-section[data-testid="stSidebar"] {
- background-color: #ccc !important;
- color: #111 !important;
+.st-key-FormSubmitter-auth_form-Se-connecter {
+ margin-left: auto;
+ margin-right: auto;
}
-section[data-testid="stSidebar"] .stButton > button {
- background-color: darkgreen !important;
+section:not([data-testid="stSidebar"]) button[data-testid="stBaseButton-primary"],
+section:not([data-testid="stSidebar"]) button[data-testid="stBaseButton-secondary"] {
color: white !important;
- font-weight: bold;
- border: 1px solid #ccc !important;
+ background: darkgreen !important;
}
-/* Footer commun */
-.wide-footer {
- width: 100vw;
- margin-left: calc(-50vw + 50%);
- margin-top: 3rem;
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
- border-top: 1px solid #ddd;
- text-align: center;
- padding-top: 1rem;
-}
-.info-footer {
- font-size: 1rem !important;
- font-weight: 800;
-}
-
-/* En-tête large */
-.wide-header {
- width: 100vw;
- margin-left: calc(-50vw + 50%);
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
- border-bottom: 1px solid #ddd;
- text-align: center;
- padding-top: 1rem;
- margin-top: -1.25em;
-}
-
-.titre-header {
- font-size: 2rem !important;
- font-weight: bolder !important;
-}
-
-/* Accessibilité RGAA pour les onglets */
-div[role="radiogroup"] > label {
- padding: 0.5em 1em;
- border-radius: 0.4em;
- margin-right: 0.5em;
- cursor: pointer;
- border: 1px solid #fff;
-}
-div[role="radiogroup"] > label[data-selected="true"] {
- font-weight: bold;
- border: 2px solid #145a1a;
-}
-
-/* Styles pour les éléments décoratifs */
-section[data-testid="stSidebar"] .decorative-heading {
- font-size: 1.25rem;
- font-weight: bold;
- margin-bottom: 0.5rem;
- text-align: center;
- color: #145a1a;
-}
-
-section[data-testid="stSidebar"] div[role="radiogroup"] {
- justify-content: center !important;
- display: flex !important;
- gap: 1rem; /* Optionnel : espace entre les boutons */
-}
-
-/* Corrige la couleur du texte des boutons de la sidebar - identique en light ou en dark */
-section[data-testid="stSidebar"] .stButton > button {
- background-color: darkgreen !important;
- color: white !important;
- font-weight: bold !important;
- border: 1px solid #ccc !important;
- width: 100%;
-}
-
-/* Translate Drag and drop and Browse files */
-/* Hide original "Drag and drop file here" text */
-div[data-testid="stFileUploaderDropzoneInstructions"]
- .st-emotion-cache-j7qwjs
- > span:nth-of-type(1) {
- visibility: hidden;
-}
-/* Insert French translation */
-div[data-testid="stFileUploaderDropzoneInstructions"]
- .st-emotion-cache-j7qwjs
- > span:nth-of-type(1)::after {
- content: "Glissez-déposez votre fichier ici";
- visibility: visible;
- display: block;
- font-size: inherit;
- color: inherit;
-}
-
-/* Hide original "Browse files" button text */
-/* Target the button within the dropzone container for uploader */
-div[data-testid="stFileUploaderDropzone"]
- button[data-testid="stBaseButton-secondary"] {
- color: transparent !important;
- position: relative;
-}
-/* Insert French translation for button */
-div[data-testid="stFileUploaderDropzone"]
- button[data-testid="stBaseButton-secondary"]::after {
- content: "Parcourir les fichiers";
- visibility: visible !important;
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- display: block;
- font-size: inherit;
- color: inherit !important;
-}
-
-/* Override Streamlit file uploader limit text to 100 Ko */
-div[data-testid="stFileUploaderDropzoneInstructions"] small {
- visibility: hidden;
-}
-div[data-testid="stFileUploaderDropzoneInstructions"] small::after {
- content: "Limite 100 Ko par fichier • JSON";
- visibility: visible;
- display: block;
- font-size: inherit;
- color: inherit;
- margin-top: 0.25em;
-}
-
-button[data-testid="stBaseButton-primary"],
-button[data-testid="stBaseButton-secondary"] {
- color: white !important;
-}
-button[data-testid="stBaseButton-primary"] p,
-,
-button[data-testid="stBaseButton-secondary"] p {
+section:not([data-testid="stSidebar"]) button[data-testid="stBaseButton-primary"] p,
+section:not([data-testid="stSidebar"]) button[data-testid="stBaseButton-secondary"] p {
color: white !important;
}
@@ -206,59 +81,35 @@ button[data-testid="stBaseButton-secondary"] p {
letter-spacing: 0.2em;
}
-/* Utilisation des variables CSS définies dans les fichiers de thème */
-
-body,
-.stApp,
-.block-container {
- background-color: var(--bg-color) !important;
- color: var(--text-color) !important;
+button[data-testid="stBaseButton-headerNoPadding"] svg {
+ fill: var(--text-color) !important;
}
-/* En-tête large */
-.wide-header {
- background-color: var(--header-bg);
+/* --- 3.2 Onglets et radiogroup --- */
+div[role="radiogroup"] > label {
+ padding: 0.5em 1em;
+ border-radius: 0.4em;
+ margin-right: 0.5em;
+ cursor: pointer;
+ border: 1px solid #fff;
}
-.titre-header {
- color: var(--header-title);
+div[role="radiogroup"] > label[data-selected="true"] {
+ font-weight: bold;
+ border: 2px solid #145a1a;
}
-/* Footer commun */
-.wide-footer {
- background-color: var(--footer-bg);
-}
-
-.info-footer {
- color: var(--footer-text);
-}
-
-/* Accessibilité RGAA pour les onglets */
section:not([data-testid="stSidebar"]) div[role="radiogroup"] > label p {
background-color: var(--radio-bg) !important;
color: var(--radio-text) !important;
}
-section:not([data-testid="stSidebar"])
- div[role="radiogroup"]
- > label[data-selected="true"] {
+section:not([data-testid="stSidebar"]) div[role="radiogroup"] > label[data-selected="true"] {
background-color: var(--radio-selected-bg) !important;
color: var(--radio-selected-text) !important;
}
-/* Graphiques */
-.stPlotlyChart text {
- fill: var(--plot-text) !important;
-}
-
-/* Paragraphes */
-section:not([data-testid="stSidebar"])
- div:not[data-testid="stElementContainer"]
- p:not(#Authentification):not(#Theme) {
- color: var(--paragraph-color) !important;
-}
-
-/* Champs de formulaire */
+/* --- 3.3 Champs de formulaire --- */
div[data-baseweb="select"],
section:not([data-testid="stSidebar"]) div[data-baseweb="base-input"],
section[data-testid="stFileUploaderDropzone"] {
@@ -267,12 +118,89 @@ section[data-testid="stFileUploaderDropzone"] {
padding: 4px;
}
-/* Détails */
-details {
- border-color: var(--details-border) !important;
+section:not([data-testid="stSidebar"]) div[data-testid="stSelectbox"] p,
+section:not([data-testid="stSidebar"]) div[data-testid="stMultiSelect"] p,
+section:not([data-testid="stSidebar"]) div[data-testid="stRadio"] p,
+section:not([data-testid="stSidebar"]) div[data-testid="stCheckbox"] p,
+section:not([data-testid="stSidebar"]) div[data-testid="stTextInput"] p,
+section:not([data-testid="stSidebar"]) div[data-testid="stTextArea"] p,
+section:not([data-testid="stSidebar"]) div[data-testid="stAlertContentInfo"] p {
+ color: var(--text-color) !important;
}
-/* Tables */
+/* ==========================================
+ 4. Header et Footer
+ ========================================== */
+
+/* --- 4.1 Header --- */
+.wide-header {
+ width: 100vw;
+ margin-left: calc(-50vw + 50%);
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+ border-bottom: 1px solid #ddd;
+ text-align: center;
+ padding-top: 1rem;
+ margin-top: -1.25em;
+ background-color: var(--header-bg);
+}
+
+.titre-header {
+ font-size: 2rem !important;
+ font-weight: bolder !important;
+ color: var(--header-title);
+}
+
+/* --- 4.2 Footer --- */
+.wide-footer {
+ width: 100vw;
+ margin-left: calc(-50vw + 50%);
+ margin-top: 3rem;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+ border-top: 1px solid #ddd;
+ text-align: center;
+ padding-top: 1rem;
+ background-color: var(--footer-bg);
+}
+
+.info-footer {
+ font-size: 1rem !important;
+ font-weight: 800;
+ color: var(--footer-text);
+}
+
+/* ==========================================
+ 5. Sidebar
+ ========================================== */
+section[data-testid="stSidebar"] {
+ background-color: #ccc !important;
+ color: #111 !important;
+}
+
+section[data-testid="stSidebar"] .stButton > button {
+ background-color: darkgreen !important;
+ color: white !important;
+ font-weight: bold !important;
+ border: 1px solid #ccc !important;
+ width: 100%;
+}
+
+section[data-testid="stSidebar"] .decorative-heading {
+ font-size: 1.25rem;
+ font-weight: bold;
+ margin-bottom: 0.5rem;
+ text-align: center;
+ color: #145a1a;
+}
+
+section[data-testid="stSidebar"] div[role="radiogroup"] {
+ justify-content: center !important;
+ display: flex !important;
+ gap: 1rem;
+}
+
+/* ==========================================
+ 6. Tables
+ ========================================== */
table {
border: 1px solid var(--table-border) !important;
border-collapse: collapse;
@@ -280,14 +208,12 @@ table {
margin-bottom: 1.5em;
}
-th,
-td {
+th, td {
border: 1px solid var(--table-border) !important;
padding: 8px;
text-align: left;
}
-/* Accessibilité RGAA */
caption {
caption-side: top;
font-weight: bold;
@@ -301,20 +227,61 @@ table[role="table"] th[scope="col"] {
background-color: var(--background-color);
}
-/* Fin de Tables */
+/* ==========================================
+ 7. Composants spécifiques
+ ========================================== */
-section:not([data-testid="stSidebar"]) div[data-testid="stSelectbox"] p,
-section:not([data-testid="stSidebar"]) div[data-testid="stMultiSelect"] p,
-section:not([data-testid="stSidebar"]) div[data-testid="stRadio"] p,
-section:not([data-testid="stSidebar"]) div[data-testid="stCheckbox"] p,
-section:not([data-testid="stSidebar"]) div[data-testid="stTextInput"] p,
-section:not([data-testid="stSidebar"]) div[data-testid="stTextArea"] p,
-section:not([data-testid="stSidebar"]) div[data-testid="stAlertContentInfo"] p {
- color: var(--text-color) !important;
+/* --- 7.1 File Uploader (traductions) --- */
+/* Hide original "Drag and drop file here" text */
+div[data-testid="stFileUploaderDropzoneInstructions"] span:nth-of-type(1) {
+ visibility: hidden;
}
-section:not([data-testid="stSidebar"]) hr {
- background-color: var(--hr-color) !important;
+/* Insert French translation */
+div[data-testid="stFileUploaderDropzoneInstructions"] span:nth-of-type(1)::after {
+ content: "Glissez-déposez votre fichier ici";
+ visibility: visible;
+ display: block;
+ font-size: inherit;
+ color: inherit;
+}
+
+/* Hide original "Browse files" button text */
+div[data-testid="stFileUploaderDropzone"] button[data-testid="stBaseButton-secondary"] {
+ color: transparent !important;
+ position: relative;
+}
+
+/* Insert French translation for button */
+div[data-testid="stFileUploaderDropzone"] button[data-testid="stBaseButton-secondary"]::after {
+ content: "Parcourir les fichiers";
+ visibility: visible !important;
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ display: block;
+ font-size: inherit;
+ color: inherit !important;
+}
+
+/* Override Streamlit file uploader limit text */
+div[data-testid="stFileUploaderDropzoneInstructions"] small {
+ visibility: hidden;
+}
+
+div[data-testid="stFileUploaderDropzoneInstructions"] small::after {
+ content: "Limite 100 Ko par fichier • JSON";
+ visibility: visible;
+ display: block;
+ font-size: inherit;
+ color: inherit;
+ margin-top: 0.25em;
+}
+
+/* --- 7.2 Graphiques --- */
+.stPlotlyChart text {
+ fill: var(--plot-text) !important;
}
.stPlotlyChart text {
@@ -325,60 +292,54 @@ section:not([data-testid="stSidebar"]) hr {
font-family: Verdana, sans-serif !important;
}
-.conteneur_commentaire {
- background: var(--background-color);
- padding: 0.5rem;
- border-radius: 8px;
- margin-bottom: 0.5rem;
- border: 1px solid #ccc;
- border-radius: 8px;
- padding: 1em;
- margin-bottom: 1em;
+/* Cache complètement la section d'actions Vega */
+.vega-actions {
+ display: none !important;
}
-.commentaire_auteur {
- color: var(--text-color) !important;
- margin: 0;
-}
-
-.commentaire_contenu {
- color: var(--text-color) !important;
- margin: 0.5rem 0 0;
-}
-
-.conteneur_ticket {
- background: var(--background-color);
- padding: 0.5rem;
- border-radius: 8px;
- margin-bottom: 0.5rem;
- border: 1px solid #ccc;
- border-radius: 8px;
- padding: 1em;
- margin-bottom: 1em;
-}
-
-.ticket_auteur {
- color: var(--text-color) !important;
- margin: 0;
-}
-
-.ticket_contenu {
- color: var(--text-color) !important;
- margin: 0.5rem 0 0;
-}
-
-button[data-testid="stBaseButton-headerNoPadding"] svg {
- fill: var(--text-color) !important;
+/* Et aussi le parent, s'il faut tout masquer */
+details[title="Click to view actions"] {
+ display: none !important;
}
+/* --- 7.3 Détails et paragraphes --- */
details {
border: 1px solid #ccc;
border-radius: 6px;
padding: 0.5em;
margin-bottom: 0.5em;
background-color: var(--background-color);
+ border-color: var(--details-border) !important;
}
+section:not([data-testid="stSidebar"]) div:not[data-testid="stElementContainer"] p:not(#Authentification):not(#Theme) {
+ color: var(--paragraph-color) !important;
+}
+
+section:not([data-testid="stSidebar"]) hr {
+ background-color: var(--hr-color) !important;
+}
+
+/* --- 7.4 Conteneurs de commentaires et tickets --- */
+.conteneur_commentaire, .conteneur_ticket {
+ background: var(--background-color);
+ padding: 1em;
+ border-radius: 8px;
+ margin-bottom: 1em;
+ border: 1px solid #ccc;
+}
+
+.commentaire_auteur, .ticket_auteur {
+ color: var(--text-color) !important;
+ margin: 0;
+}
+
+.commentaire_contenu, .ticket_contenu {
+ color: var(--text-color) !important;
+ margin: 0.5rem 0 0;
+}
+
+/* --- 7.5 Blocs mathématiques --- */
.math-block {
display: block;
text-align: center;
@@ -394,16 +355,15 @@ details {
display: inline-block;
}
-/* Cache complètement la section d’actions Vega */
-.vega-actions {
- display: none !important;
-}
-
-/* Et aussi le parent, s’il faut tout masquer */
-details[title="Click to view actions"] {
- display: none !important;
-}
-
+/* ==========================================
+ 8. Éléments spécifiques
+ ========================================== */
div.stElementContainer.element-container.st-key-nom_utilisateur {
display: none !important;
}
+
+.st-key-telecharger_fiche_pdf {
+ margin-left: auto;
+ margin-right: auto;
+ margin-top: 1rem;
+}
\ No newline at end of file
diff --git a/components/connexion.py b/components/connexion.py
index aefa031..660ecbd 100644
--- a/components/connexion.py
+++ b/components/connexion.py
@@ -38,20 +38,11 @@ def connexion():
if not st.session_state.logged_in:
with st.form("auth_form"):
- # 🧠 Ajout d'un champ identifiant fictif pour activer l'autocomplétion navigateur
+ # Ajout d'un champ identifiant fictif pour activer l'autocomplétion navigateur
+ # et permettre de stocker le token comme un mot de passe par le navigateur
identifiant = st.text_input("Identifiant_token", value="fabnum-connexion", key="nom_utilisateur")
token = st.text_input("Token d'accès personnel Gitea", type="password")
submitted = st.form_submit_button("Se connecter")
- st.markdown("""
-
- """, unsafe_allow_html=True)
if submitted and token:
erreur = True
diff --git a/utils/gitea.py b/utils/gitea.py
index 4772fc2..840efe8 100644
--- a/utils/gitea.py
+++ b/utils/gitea.py
@@ -1,24 +1,44 @@
import base64
import requests
import os
+import streamlit as st
from dateutil import parser
from datetime import datetime, timezone
import logging
from config import GITEA_URL, GITEA_TOKEN, ORGANISATION, DEPOT_FICHES, DEPOT_CODE, ENV, ENV_CODE, DOT_FILE
+def lire_fichier_local(nom_fichier):
+ with open(nom_fichier, "r", encoding="utf-8") as f:
+ contenu_md = f.read()
+ return contenu_md
def charger_instructions_depuis_gitea(nom_fichier="Instructions.md"):
headers = {"Authorization": f"token {GITEA_TOKEN}"}
url = f"{GITEA_URL}/repos/{ORGANISATION}/{DEPOT_FICHES}/contents/{nom_fichier}?ref={ENV}"
try:
- response = requests.get(url, headers=headers)
- response.raise_for_status()
- data = response.json()
- contenu_md = base64.b64decode(data["content"]).decode("utf-8")
- return contenu_md
+ # Vérifier si une version plus récente existe sur le dépôt
+ remote_last_modified = recuperer_date_dernier_commit(f"{GITEA_URL}/repos/{ORGANISATION}/{DEPOT_FICHES}/commits?path={nom_fichier}&sha={ENV}")
+ local_last_modified = datetime.fromtimestamp(os.path.getmtime(nom_fichier), tz=timezone.utc) if os.path.exists(nom_fichier) else None
+
+ # Si le fichier local n'existe pas ou si la version distante est plus récente
+ if not local_last_modified or (remote_last_modified and remote_last_modified > local_last_modified):
+ response = requests.get(url, headers=headers)
+ response.raise_for_status()
+ data = response.json()
+ contenu_md = base64.b64decode(data["content"]).decode("utf-8")
+ # Sauvegarder en local
+ with open(nom_fichier, "w", encoding="utf-8") as f:
+ f.write(contenu_md)
+ return contenu_md
+ else:
+ # Lire depuis le cache local
+ return lire_fichier_local(nom_fichier)
except Exception as e:
- logging.error(f"Erreur chargement instructions Gitea : {e}")
+ st.error(f"Erreur chargement instructions Gitea : {e}")
+ # Essayer de charger depuis le cache local en cas d'erreur
+ if os.path.exists(nom_fichier):
+ return lire_fichier_local(nom_fichier)
return None