273 lines
14 KiB
HTML
273 lines
14 KiB
HTML
<!DOCTYPE html>
|
|
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
|
|
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
|
xmlns:f="http://xmlns.jcp.org/jsf/core"
|
|
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
|
|
xmlns:p="http://primefaces.org/ui"
|
|
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
|
|
template="/templates/main-template.xhtml">
|
|
|
|
<ui:param name="page" value="#{auditConsultationBean}"/>
|
|
<ui:define name="title">Journal d'Audit - Lions User Manager</ui:define>
|
|
|
|
<ui:define name="content">
|
|
<!-- En-tête -->
|
|
<ui:include src="/templates/components/layout/page-header.xhtml">
|
|
<ui:param name="icon" value="pi pi-history text-orange-500" />
|
|
<ui:param name="title" value="Journal d'Audit" />
|
|
<ui:param name="description" value="Consultation des logs d'audit et statistiques" />
|
|
<ui:define name="actions">
|
|
<h:form id="formActionsAudit">
|
|
<div class="flex gap-2">
|
|
<ui:include src="/templates/components/shared/buttons/button-user-action.xhtml">
|
|
<ui:param name="value" value="Exporter CSV" />
|
|
<ui:param name="icon" value="pi pi-download" />
|
|
<ui:param name="hasAction" value="true" />
|
|
<ui:param name="action" value="#{auditConsultationBean.exportToCSV}" />
|
|
<ui:param name="severity" value="success" />
|
|
</ui:include>
|
|
</div>
|
|
</h:form>
|
|
</ui:define>
|
|
</ui:include>
|
|
|
|
<!-- Statistiques avec composants réutilisables -->
|
|
<ui:include src="/templates/components/shared/dashboard/kpi-group.xhtml">
|
|
<ui:param name="title" value="Statistiques d'Audit" />
|
|
<ui:param name="columns" value="4" />
|
|
<ui:define name="kpi-content">
|
|
<ui:include src="/templates/components/shared/cards/kpi-card.xhtml">
|
|
<ui:param name="title" value="Total Actions" />
|
|
<ui:param name="value" value="#{auditConsultationBean.totalRecords}" />
|
|
<ui:param name="icon" value="pi-history" />
|
|
<ui:param name="iconColor" value="blue-600" />
|
|
</ui:include>
|
|
<ui:include src="/templates/components/shared/cards/kpi-card.xhtml">
|
|
<ui:param name="title" value="Actions Réussies" />
|
|
<ui:param name="value" value="#{auditConsultationBean.successCount}" />
|
|
<ui:param name="icon" value="pi-check-circle" />
|
|
<ui:param name="iconColor" value="green-600" />
|
|
</ui:include>
|
|
<ui:include src="/templates/components/shared/cards/kpi-card.xhtml">
|
|
<ui:param name="title" value="Actions Échouées" />
|
|
<ui:param name="value" value="#{auditConsultationBean.failureCount}" />
|
|
<ui:param name="icon" value="pi-times-circle" />
|
|
<ui:param name="iconColor" value="red-600" />
|
|
</ui:include>
|
|
<ui:include src="/templates/components/shared/cards/kpi-card.xhtml">
|
|
<ui:param name="title" value="Taux de Réussite" />
|
|
<ui:param name="value" value="#{auditConsultationBean.totalRecords > 0 ? (auditConsultationBean.successCount * 100 / auditConsultationBean.totalRecords) : 0}%" />
|
|
<ui:param name="icon" value="pi-percentage" />
|
|
<ui:param name="iconColor" value="purple-600" />
|
|
</ui:include>
|
|
</ui:define>
|
|
</ui:include>
|
|
|
|
<!-- Filtres de recherche -->
|
|
<div class="card mb-3">
|
|
<h:form id="formFilters">
|
|
<p:panelGrid columns="3" styleClass="w-full" columnClasses="col-12 md:col-4">
|
|
<p:outputLabel for="acteurFilter" value="Acteur" />
|
|
<p:inputText id="acteurFilter"
|
|
value="#{auditConsultationBean.acteurUsername}"
|
|
placeholder="Nom d'utilisateur..."
|
|
styleClass="w-full" />
|
|
|
|
<p:outputLabel for="typeActionFilter" value="Type d'action" />
|
|
<p:selectOneMenu id="typeActionFilter"
|
|
value="#{auditConsultationBean.selectedTypeAction}"
|
|
styleClass="w-full">
|
|
<f:selectItem itemLabel="Tous les types" itemValue="" />
|
|
<f:selectItems value="#{auditConsultationBean.typeActionOptions}" />
|
|
</p:selectOneMenu>
|
|
|
|
<p:outputLabel for="succesFilter" value="Résultat" />
|
|
<p:selectOneMenu id="succesFilter"
|
|
value="#{auditConsultationBean.succes}"
|
|
styleClass="w-full">
|
|
<f:selectItem itemLabel="Tous" itemValue="" />
|
|
<f:selectItem itemLabel="Succès" itemValue="true" />
|
|
<f:selectItem itemLabel="Échec" itemValue="false" />
|
|
</p:selectOneMenu>
|
|
|
|
<p:outputLabel for="dateDebutFilter" value="Date début" />
|
|
<p:calendar id="dateDebutFilter"
|
|
value="#{auditConsultationBean.dateDebut}"
|
|
pattern="dd/MM/yyyy"
|
|
styleClass="w-full" />
|
|
|
|
<p:outputLabel for="dateFinFilter" value="Date fin" />
|
|
<p:calendar id="dateFinFilter"
|
|
value="#{auditConsultationBean.dateFin}"
|
|
pattern="dd/MM/yyyy"
|
|
styleClass="w-full" />
|
|
|
|
<p:outputLabel for="ressourceFilter" value="Type ressource" />
|
|
<p:inputText id="ressourceFilter"
|
|
value="#{auditConsultationBean.ressourceType}"
|
|
placeholder="USER, ROLE..."
|
|
styleClass="w-full" />
|
|
</p:panelGrid>
|
|
|
|
<div class="flex gap-2 justify-content-end mt-3">
|
|
<p:commandButton
|
|
value="Rechercher"
|
|
icon="pi pi-search"
|
|
styleClass="p-button-primary"
|
|
action="#{auditConsultationBean.searchLogs}"
|
|
update="formAuditLogs:auditLogsTable" />
|
|
<p:commandButton
|
|
value="Réinitialiser"
|
|
icon="pi pi-refresh"
|
|
styleClass="p-button-secondary"
|
|
action="#{auditConsultationBean.resetFilters}"
|
|
update="formAuditLogs:auditLogsTable @form" />
|
|
</div>
|
|
</h:form>
|
|
</div>
|
|
|
|
<!-- Liste des logs avec p:dataTable -->
|
|
<div class="card">
|
|
<h:form id="formAuditLogs">
|
|
<h5>Logs d'Audit</h5>
|
|
<p:dataTable
|
|
id="auditLogsTable"
|
|
value="#{auditConsultationBean.auditLogs}"
|
|
var="log"
|
|
rowKey="#{log.id}"
|
|
paginator="true"
|
|
rows="20"
|
|
rowsPerPageTemplate="10,20,50,100"
|
|
emptyMessage="Aucun log d'audit trouvé"
|
|
styleClass="w-full">
|
|
|
|
<!-- Colonne Statut -->
|
|
<p:column headerText="Statut" style="width: 5rem">
|
|
<p:tag
|
|
value="#{log.succes ? 'Succès' : 'Échec'}"
|
|
severity="#{log.succes ? 'success' : 'danger'}"
|
|
styleClass="text-xs" />
|
|
</p:column>
|
|
|
|
<!-- Colonne Type d'action -->
|
|
<p:column headerText="Type d'action" sortBy="#{log.typeAction}" style="width: 15%">
|
|
<strong class="text-900">#{log.typeAction}</strong>
|
|
</p:column>
|
|
|
|
<!-- Colonne Acteur -->
|
|
<p:column headerText="Acteur" sortBy="#{log.acteurUsername}" style="width: 15%">
|
|
<div class="flex align-items-center gap-2">
|
|
<i class="pi pi-user text-color-secondary"></i>
|
|
<span>#{log.acteurUsername}</span>
|
|
</div>
|
|
</p:column>
|
|
|
|
<!-- Colonne Ressource -->
|
|
<p:column headerText="Ressource" style="width: 12%">
|
|
<div class="flex align-items-center gap-2">
|
|
<i class="pi pi-database text-color-secondary"></i>
|
|
<span>#{log.ressourceType}</span>
|
|
</div>
|
|
</p:column>
|
|
|
|
<!-- Colonne Date -->
|
|
<p:column headerText="Date" sortBy="#{log.dateAction}" style="width: 15%">
|
|
<div class="flex align-items-center gap-2">
|
|
<i class="pi pi-calendar text-color-secondary"></i>
|
|
<span>#{log.dateAction}</span>
|
|
</div>
|
|
</p:column>
|
|
|
|
<!-- Colonne Détails -->
|
|
<p:column headerText="Détails" style="width: 20%">
|
|
<c:if test="#{not empty log.details}">
|
|
<span class="text-color-secondary text-sm">#{log.details}</span>
|
|
</c:if>
|
|
<c:if test="#{empty log.details}">
|
|
<span class="text-color-secondary text-sm">-</span>
|
|
</c:if>
|
|
</p:column>
|
|
|
|
<!-- Colonne IP -->
|
|
<p:column headerText="IP" style="width: 10%">
|
|
<c:if test="#{not empty log.adresseIp}">
|
|
<span class="text-color-secondary text-sm">#{log.adresseIp}</span>
|
|
</c:if>
|
|
<c:if test="#{empty log.adresseIp}">
|
|
<span class="text-color-secondary text-sm">-</span>
|
|
</c:if>
|
|
</p:column>
|
|
|
|
<!-- Colonne Actions -->
|
|
<p:column headerText="Actions" style="width: 8%">
|
|
<p:commandButton
|
|
icon="pi pi-eye"
|
|
styleClass="p-button-text p-button-sm"
|
|
title="Voir les détails"
|
|
onclick="PF('auditLogDetailsDialog').show()">
|
|
<f:setPropertyActionListener target="#{auditConsultationBean.selectedLog}" value="#{log}" />
|
|
</p:commandButton>
|
|
</p:column>
|
|
</p:dataTable>
|
|
</h:form>
|
|
</div>
|
|
|
|
<!-- Dialog de détails -->
|
|
<p:dialog
|
|
id="auditLogDetailsDialog"
|
|
widgetVar="auditLogDetailsDialog"
|
|
header="Détails du Log d'Audit"
|
|
modal="true"
|
|
resizable="false"
|
|
styleClass="w-full md:w-30rem">
|
|
<h:form id="formAuditLogDetails">
|
|
<c:if test="#{not empty auditConsultationBean.selectedLog}">
|
|
<div class="flex flex-column gap-3">
|
|
<div>
|
|
<strong>Type d'action:</strong>
|
|
<p>#{auditConsultationBean.selectedLog.typeAction}</p>
|
|
</div>
|
|
<div>
|
|
<strong>Acteur:</strong>
|
|
<p>#{auditConsultationBean.selectedLog.acteurUsername}</p>
|
|
</div>
|
|
<div>
|
|
<strong>Ressource:</strong>
|
|
<p>#{auditConsultationBean.selectedLog.ressourceType} - #{auditConsultationBean.selectedLog.ressourceId}</p>
|
|
</div>
|
|
<div>
|
|
<strong>Date:</strong>
|
|
<p>#{auditConsultationBean.selectedLog.dateAction}</p>
|
|
</div>
|
|
<c:if test="#{not empty auditConsultationBean.selectedLog.details}">
|
|
<div>
|
|
<strong>Détails:</strong>
|
|
<p>#{auditConsultationBean.selectedLog.details}</p>
|
|
</div>
|
|
</c:if>
|
|
<c:if test="#{not empty auditConsultationBean.selectedLog.adresseIp}">
|
|
<div>
|
|
<strong>Adresse IP:</strong>
|
|
<p>#{auditConsultationBean.selectedLog.adresseIp}</p>
|
|
</div>
|
|
</c:if>
|
|
<c:if test="#{not empty auditConsultationBean.selectedLog.userAgent}">
|
|
<div>
|
|
<strong>User Agent:</strong>
|
|
<p>#{auditConsultationBean.selectedLog.userAgent}</p>
|
|
</div>
|
|
</c:if>
|
|
<c:if test="#{not empty auditConsultationBean.selectedLog.messageErreur}">
|
|
<div>
|
|
<strong class="text-red-600">Message d'erreur:</strong>
|
|
<p class="text-red-600">#{auditConsultationBean.selectedLog.messageErreur}</p>
|
|
</div>
|
|
</c:if>
|
|
</div>
|
|
</c:if>
|
|
</h:form>
|
|
</p:dialog>
|
|
</ui:define>
|
|
|
|
</ui:composition>
|