Update - Lions User Manager - Client (Quarkus PrimeFaces Freya)

This commit is contained in:
dahoud
2025-12-06 22:07:05 +00:00
parent 53ea02ccad
commit 51d087e5be
189 changed files with 38558 additions and 1 deletions

View File

@@ -0,0 +1,272 @@
<!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>