From ab8b4ea4872b8d23fab773d3943981fd2442b48e Mon Sep 17 00:00:00 2001 From: Daniel Allaire Date: Sun, 31 May 2026 12:54:35 -0400 Subject: [PATCH] Optimiser affichage du journal --- frontend/src/pages/JournalActions.jsx | 155 ++++++++++++++++---------- 1 file changed, 98 insertions(+), 57 deletions(-) diff --git a/frontend/src/pages/JournalActions.jsx b/frontend/src/pages/JournalActions.jsx index 02da6ad..967b5d1 100644 --- a/frontend/src/pages/JournalActions.jsx +++ b/frontend/src/pages/JournalActions.jsx @@ -26,6 +26,8 @@ export default function JournalActions() { const [filtres, setFiltres] = useState({ date_debut: '', date_fin: '', membre_id: '', table_cible: '', action: '', q: '' }); const [loading, setLoading] = useState(true); const [error, setError] = useState(''); + const [ouvertHistorique, setOuvertHistorique] = useState(null); + const [ouvertTechnique, setOuvertTechnique] = useState(null); const historiqueQuery = (source = filtres) => { const params = new URLSearchParams({ limite: '100' }); @@ -60,6 +62,12 @@ export default function JournalActions() { dateStyle: 'medium', timeStyle: 'short', }); + const formatDateCompacte = (value) => new Date(value).toLocaleString('fr-CA', { + month: 'short', + day: 'numeric', + hour: '2-digit', + minute: '2-digit', + }); const formatValeur = (value) => { if (value === null || value === undefined || value === '') return '—'; if (typeof value === 'boolean') return value ? 'oui' : 'non'; @@ -73,6 +81,18 @@ export default function JournalActions() { .map((cle) => [cle, avant?.[cle], apres?.[cle]]) .filter(([, a, b]) => JSON.stringify(a) !== JSON.stringify(b)); }; + const resumeChangements = (item) => { + const lignes = changements(item.avant, item.apres); + if (lignes.length === 0 && item.avant && !item.apres) { + return Object.keys(item.avant).slice(0, 2).join(', ') || item.raison; + } + if (lignes.length === 0) return item.raison; + const resume = lignes.slice(0, 2) + .map(([cle, avant, apres]) => `${cle}: ${formatValeur(avant)} → ${formatValeur(apres)}`) + .join(' · '); + return lignes.length > 2 ? `${resume} · +${lignes.length - 2}` : resume; + }; + const domaineLabel = (value) => DOMAINES.find(([id]) => id === value)?.[1] || value || '—'; const updateFiltre = (key, value) => setFiltres((f) => ({ ...f, [key]: value })); const resetFiltres = () => { const vides = { date_debut: '', date_fin: '', membre_id: '', table_cible: '', action: '', q: '' }; @@ -144,66 +164,87 @@ export default function JournalActions() { {!loading && tab === 'technique' && actions.length === 0 && (

Aucune action technique journalisée.

)} - {tab === 'historique' && historique.map((item) => ( -
-
-
-

{item.raison}

-

- {formatDate(item.cree_le)} · {item.membre_prenom || item.membre_id || 'Membre inconnu'} -

-
- - {item.action} - -
- {item.apres && changements(item.avant, item.apres).length > 0 && ( -
- {changements(item.avant, item.apres).map(([cle, avant, apres]) => ( -
- {cle} - - {formatValeur(avant)} - → - {formatValeur(apres)} - + {tab === 'historique' && historique.map((item) => { + const ouvert = ouvertHistorique === item.id; + const lignes = changements(item.avant, item.apres); + return ( +
+ + {ouvert && ( +
+
+

{item.raison}

+

+ {formatDate(item.cree_le)} · {item.membre_prenom || item.membre_id || 'Membre inconnu'} +

- ))} -
- )} - {item.avant && !item.apres && ( -
- {Object.entries(item.avant).map(([cle, valeur]) => ( -

{cle}: {formatValeur(valeur)}

- ))} -
- )} -
-

Objet: {item.table_cible} · {item.objet_id}

-
-
- ))} - {tab === 'technique' && actions.map((action) => ( -
-
-
-

{action.methode} {action.chemin}

-

{formatDate(action.cree_le)}

-
- - {action.statut_http} - -
-
-

Membre: {action.membre_id}

- {action.admin_id &&

Admin: {action.admin_id}

} - {action.adresse_ip &&

IP: {action.adresse_ip}

} - {action.details?.impersonification && ( -

Action faite en impersonification

+ {lignes.length > 0 && ( +
+ {lignes.map(([cle, avant, apres]) => ( +
+ {cle} + + {formatValeur(avant)} + → + {formatValeur(apres)} + +
+ ))} +
+ )} + {item.avant && !item.apres && ( +
+ {Object.entries(item.avant).map(([cle, valeur]) => ( +

{cle}: {formatValeur(valeur)}

+ ))} +
+ )} +
+

Domaine
{domaineLabel(item.table_cible)}

+

Action
{item.action}

+

Objet
{item.objet_id}

+ {item.chemin_api &&

API
{item.chemin_api}

} +
+
)}
-
- ))} + ); + })} + {tab === 'technique' && actions.map((action) => { + const ouvert = ouvertTechnique === action.id; + return ( +
+ + {ouvert && ( +
+

Date: {formatDate(action.cree_le)}

+

Membre: {action.membre_id}

+ {action.admin_id &&

Admin: {action.admin_id}

} + {action.adresse_ip &&

IP: {action.adresse_ip}

} + {action.details?.impersonification && ( +

Action faite en impersonification

+ )} +
+ )} +
+ ); + })}
);