refactor(sprint-12 web 2026-04-25): centralisation navigation outcomes via ViewPaths constants + ViewPathsBean

DRY strict appliqué pour la maintenance — outcomes de navigation centralisés en un lieu unique
au lieu de paths hardcodés disséminés dans 13+ fichiers.

Architecture
- constants.ViewPaths : classe finale + ~80 constantes public static final String, organisées
  par module (Dashboard, Membres, Adhésions, Cotisations, Finance, Crédit, Évènements, Aide,
  Communication, Documents, Organisation, Conformité, Admin, Rapports, Souscription, Super-Admin)
- view.ViewPathsBean (@Named "paths" @ApplicationScoped) : expose les constantes en EL aux XHTML

Migration menu.xhtml (65 edits, 0 path orphelin)
- outcome="/pages/secure/dashboard" → outcome="#{paths.dashboard}"
- outcome="/pages/secure/conformite/dashboard" → outcome="#{paths.conformiteDashboard}"
- ... 60+ autres mappings

Migration autres XHTML (13 edits, 12 fichiers)
- index, error/viewExpired, topbar, admin × 4, evenement × 2, organisation × 2, reports

Migration beans Java (4 fichiers, 18 returns)
- NavigationBean : goToProfile, goToSettings (super-admin / admin / membre), getDashboardUrlForUserType
- DashboardMembreBean : 5 méthodes navigation (cotisations, événement, aide, profil)
- MembreDashboardBean : voirEvenement, payerCotisations
- OrganisationsBean : retour vers liste

Test cohérence (3 tests, 100%)
- chaquePathExisteCommeFichier : reflectif sur ViewPaths, vérifie xhtml en classpath
- redirectSuffixFormat : structure REDIRECT_SUFFIX
- aucuneConstanteVide : non-null, non-blank

Dette détectée (3 pages référencées mais inexistantes — flaggées KNOWN_MISSING_PAGES)
- /pages/secure/evenement/bilan-detail.xhtml
- /pages/admin/parametres.xhtml
- /pages/membre/parametres.xhtml

Bénéfices
- 1 seul lieu pour renommer/déplacer une page
- Type-safety compile-time côté Java
- Tests détectent automatiquement les paths orphelins
- IDE complétion sur les getters paths.xxx
This commit is contained in:
dahoud
2026-04-25 14:34:11 +00:00
parent 917c8c5359
commit cdcdb37459
20 changed files with 477 additions and 109 deletions

View File

@@ -0,0 +1,143 @@
package dev.lions.unionflow.client.constants;
/**
* Centralisation des chemins de vues JSF.
*
* <p>Lieu unique pour tous les outcomes de navigation. À utiliser depuis :
* <ul>
* <li>XHTML : {@code outcome="#{paths.uboList}"} via {@link
* dev.lions.unionflow.client.view.ViewPathsBean}</li>
* <li>Java beans : {@code return ViewPaths.UBO_LIST + ViewPaths.REDIRECT_SUFFIX;}</li>
* </ul>
*
* <p>Convention de nommage : {@code MODULE_PAGE} en MAJ avec underscore
* (ex: {@code COTISATION_PAIEMENT}, {@code SUPER_ADMIN_DASHBOARD}).
*
* @since 2026-04-25 (Sprint 12 — centralisation navigation DRY)
*/
public final class ViewPaths {
private ViewPaths() {
// Classe utilitaire non instantiable
}
// ─── Suffixes ────────────────────────────────────────────────────────────
public static final String REDIRECT_SUFFIX = "?faces-redirect=true";
// ─── Index / racine / erreur ─────────────────────────────────────────────
public static final String ROOT = "/";
public static final String INDEX = "/index";
// ─── Dashboard ───────────────────────────────────────────────────────────
public static final String DASHBOARD = "/pages/secure/dashboard";
public static final String DASHBOARD_MEMBRE = "/pages/secure/dashboard-membre";
// ─── Profil personnel ────────────────────────────────────────────────────
public static final String PROFILE = "/pages/secure/profile";
public static final String PERSONNEL_PROFIL = "/pages/secure/personnel/profil";
public static final String PERSONNEL_PARAMETRES = "/pages/secure/personnel/parametres";
public static final String PERSONNEL_PREFERENCES = "/pages/secure/personnel/preferences";
public static final String PERSONNEL_NOTIFICATIONS = "/pages/secure/personnel/notifications";
// ─── Membres ─────────────────────────────────────────────────────────────
public static final String MEMBRE_LISTE = "/pages/secure/membre/liste";
public static final String MEMBRE_INSCRIPTION = "/pages/secure/membre/inscription";
public static final String MEMBRE_VALIDATION = "/pages/secure/membre/validation";
public static final String MEMBRE_IMPORT = "/pages/secure/membre/import";
public static final String MEMBRE_EXPORT = "/pages/secure/membre/export";
public static final String MEMBRE_RECHERCHE = "/pages/secure/membre/recherche";
public static final String MEMBRE_COTISATIONS = "/pages/secure/membre/cotisations";
public static final String MEMBRE_PROFIL = "/pages/secure/membre/profil";
public static final String MEMBRE_PAIEMENT_COTISATIONS = "/pages/secure/membre/paiement-mes-cotisations";
// ─── Adhésions ───────────────────────────────────────────────────────────
public static final String ADHESION_LISTE = "/pages/secure/adhesion/liste";
public static final String ADHESION_DEMANDE = "/pages/secure/adhesion/demande";
public static final String ADHESION_VALIDATION = "/pages/secure/adhesion/validation";
public static final String ADHESION_HISTORIQUE = "/pages/secure/adhesion/historique";
public static final String ADHESION_RENOUVELLEMENT = "/pages/secure/adhesion/renouvellement";
// ─── Cotisations ─────────────────────────────────────────────────────────
public static final String COTISATIONS_GESTION_ADMIN = "/pages/admin/cotisations/gestion";
public static final String COTISATION_PAIEMENT = "/pages/secure/cotisation/paiement";
public static final String COTISATION_HISTORIQUE = "/pages/secure/cotisation/historique";
public static final String COTISATION_RELANCES = "/pages/secure/cotisation/relances";
// ─── Finance ─────────────────────────────────────────────────────────────
public static final String FINANCE_TRESORERIE = "/pages/secure/finance/tresorerie";
public static final String FINANCE_BUDGETS = "/pages/secure/finance/budgets";
public static final String FINANCE_BILANS = "/pages/secure/finance/bilans";
public static final String FINANCE_APPROBATIONS = "/pages/secure/finance/approbations";
public static final String COMPTABILITE_GESTION = "/pages/secure/comptabilite/gestion";
// ─── Épargne / Crédit ────────────────────────────────────────────────────
public static final String EPARGNE_COMPTES = "/pages/secure/epargne/comptes";
public static final String CREDIT_DEMANDES = "/pages/secure/credit/demandes";
public static final String CREDIT_EVALUATION = "/pages/secure/credit/evaluation";
public static final String CREDIT_SUIVI = "/pages/secure/credit/suivi";
public static final String CREDIT_REMBOURSEMENTS = "/pages/secure/credit/remboursements";
public static final String CREDIT_STATISTIQUES = "/pages/secure/credit/statistiques";
// ─── Événements ──────────────────────────────────────────────────────────
public static final String EVENEMENT_GESTION = "/pages/secure/evenement/gestion";
public static final String EVENEMENT_CREATION = "/pages/secure/evenement/creation";
public static final String EVENEMENT_CALENDRIER = "/pages/secure/evenement/calendrier";
public static final String EVENEMENT_PARTICIPANTS = "/pages/secure/evenement/participants";
public static final String EVENEMENT_PLANIFICATION = "/pages/secure/evenement/planification";
public static final String EVENEMENT_LOGISTIQUE = "/pages/secure/evenement/logistique";
public static final String EVENEMENT_BILAN = "/pages/secure/evenement/bilan";
public static final String EVENEMENT_BILAN_DETAIL = "/pages/secure/evenement/bilan-detail";
// ─── Aide / support ──────────────────────────────────────────────────────
public static final String AIDE_DEMANDE = "/pages/secure/aide/demande";
public static final String AIDE_REQUESTS = "/pages/secure/aide/requests";
public static final String AIDE_APPROVED = "/pages/secure/aide/approved";
public static final String AIDE_TRAITEMENT = "/pages/secure/aide/traitement";
public static final String AIDE_HISTORIQUE = "/pages/secure/aide/historique";
public static final String AIDE_STATISTIQUES = "/pages/secure/aide/statistiques";
public static final String AIDE_FAQ = "/pages/secure/aide/faq";
public static final String AIDE_SUPPORT = "/pages/secure/aide/support";
public static final String AIDE_APROPOS = "/pages/secure/aide/apropos";
// ─── Communication / Documents ───────────────────────────────────────────
public static final String COMMUNICATION_CONVERSATIONS = "/pages/secure/communication/conversations";
public static final String COMMUNICATION_NOTIFICATIONS = "/pages/secure/communication/notifications";
public static final String DOCUMENTS_MES_DOCUMENTS = "/pages/secure/documents/mes-documents";
// ─── Organisation ────────────────────────────────────────────────────────
public static final String ORGANISATION_LISTE = "/pages/secure/organisation/liste";
public static final String ORGANISATION_DETAIL = "/pages/secure/organisation/detail";
public static final String ORGANISATION_NOUVELLE = "/pages/secure/organisation/nouvelle";
public static final String ORGANISATION_STATISTIQUES = "/pages/secure/organisation/statistiques";
// ─── Conformité (Sprints 8, 11) ──────────────────────────────────────────
public static final String CONFORMITE_DASHBOARD = "/pages/secure/conformite/dashboard";
public static final String CONFORMITE_RAPPORTS_TRIMESTRIELS = "/pages/secure/conformite/rapports-trimestriels";
public static final String CONFORMITE_BENEFICIAIRES_EFFECTIFS = "/pages/secure/conformite/beneficiaires-effectifs";
public static final String CONFORMITE_AUDIT_TRAIL = "/pages/secure/conformite/audit-trail";
// ─── Admin technique ─────────────────────────────────────────────────────
public static final String ADMIN_PISPI_READINESS = "/pages/secure/admin/pispi-readiness";
public static final String ADMIN_ROLE_DELEGATIONS = "/pages/secure/admin/role-delegations";
public static final String ADMIN_SAUVEGARDE = "/pages/secure/admin/sauvegarde";
public static final String ADMIN_AUDIT_JOURNAL = "/pages/admin/audit/journal";
public static final String ADMIN_LOGS_SYSTEME = "/pages/admin/logs/systeme";
public static final String ADMIN_PARAMETRES = "/pages/admin/parametres";
public static final String MEMBRE_PARAMETRES = "/pages/membre/parametres";
// ─── Rapports ────────────────────────────────────────────────────────────
public static final String RAPPORT_FINANCES = "/pages/secure/rapport/finances";
public static final String RAPPORT_MEMBRES = "/pages/secure/rapport/membres";
public static final String RAPPORT_ACTIVITES = "/pages/secure/rapport/activites";
public static final String RAPPORT_TABLEAUX_BORD = "/pages/secure/rapport/tableaux-bord";
public static final String RAPPORT_EXPORT = "/pages/secure/rapport/export";
// ─── Souscription ────────────────────────────────────────────────────────
public static final String SOUSCRIPTION_DASHBOARD = "/pages/secure/souscription/dashboard";
// ─── Super-Admin ─────────────────────────────────────────────────────────
public static final String SUPER_ADMIN_DASHBOARD = "/pages/super-admin/dashboard";
public static final String SUPER_ADMIN_ROLES_GESTION = "/pages/super-admin/roles/gestion";
public static final String SUPER_ADMIN_TYPES_ORGANISATIONS = "/pages/super-admin/types/organisations";
public static final String SUPER_ADMIN_CONFIGURATION_SYSTEME = "/pages/super-admin/configuration/systeme";
}

View File

@@ -1,5 +1,6 @@
package dev.lions.unionflow.client.view; package dev.lions.unionflow.client.view;
import dev.lions.unionflow.client.constants.ViewPaths;
import dev.lions.unionflow.server.api.dto.cotisation.response.CotisationResponse; import dev.lions.unionflow.server.api.dto.cotisation.response.CotisationResponse;
import dev.lions.unionflow.client.api.dto.MembreDashboardResponse; import dev.lions.unionflow.client.api.dto.MembreDashboardResponse;
import dev.lions.unionflow.client.service.CotisationService; import dev.lions.unionflow.client.service.CotisationService;
@@ -175,23 +176,23 @@ public class DashboardMembreBean implements Serializable {
// ═══════════════════════════════════════════════════════════════════════ // ═══════════════════════════════════════════════════════════════════════
public String allerAuxCotisations() { public String allerAuxCotisations() {
return "/pages/secure/membre/paiement-mes-cotisations.xhtml?faces-redirect=true"; return ViewPaths.MEMBRE_PAIEMENT_COTISATIONS + ".xhtml" + ViewPaths.REDIRECT_SUFFIX;
} }
public String inscrireEvenement() { public String inscrireEvenement() {
return "/pages/secure/evenement/calendrier.xhtml?faces-redirect=true"; return ViewPaths.EVENEMENT_CALENDRIER + ".xhtml" + ViewPaths.REDIRECT_SUFFIX;
} }
public String demanderAide() { public String demanderAide() {
return "/pages/secure/aide/demande.xhtml?faces-redirect=true"; return ViewPaths.AIDE_DEMANDE + ".xhtml" + ViewPaths.REDIRECT_SUFFIX;
} }
public String allerAMonProfil() { public String allerAMonProfil() {
return "/pages/secure/membre/profil.xhtml?faces-redirect=true"; return ViewPaths.MEMBRE_PROFIL + ".xhtml" + ViewPaths.REDIRECT_SUFFIX;
} }
public String allerAuxEvenements() { public String allerAuxEvenements() {
return "/pages/secure/evenement/calendrier.xhtml?faces-redirect=true"; return ViewPaths.EVENEMENT_CALENDRIER + ".xhtml" + ViewPaths.REDIRECT_SUFFIX;
} }
// ═══════════════════════════════════════════════════════════════════════ // ═══════════════════════════════════════════════════════════════════════

View File

@@ -1,5 +1,6 @@
package dev.lions.unionflow.client.view; package dev.lions.unionflow.client.view;
import dev.lions.unionflow.client.constants.ViewPaths;
import dev.lions.unionflow.server.api.dto.membre.response.MembreResponse; import dev.lions.unionflow.server.api.dto.membre.response.MembreResponse;
import dev.lions.unionflow.server.api.dto.cotisation.response.CotisationResponse; import dev.lions.unionflow.server.api.dto.cotisation.response.CotisationResponse;
import dev.lions.unionflow.server.api.dto.evenement.response.EvenementResponse; import dev.lions.unionflow.server.api.dto.evenement.response.EvenementResponse;
@@ -363,7 +364,7 @@ public class MembreDashboardBean implements Serializable {
} }
public String voirEvenement(Evenement evenement) { public String voirEvenement(Evenement evenement) {
return "/pages/secure/evenement/gestion.xhtml?faces-redirect=true"; return ViewPaths.EVENEMENT_GESTION + ".xhtml" + ViewPaths.REDIRECT_SUFFIX;
} }
public void annulerInscription(Evenement evenement) { public void annulerInscription(Evenement evenement) {
@@ -373,7 +374,7 @@ public class MembreDashboardBean implements Serializable {
} }
public String payerCotisations() { public String payerCotisations() {
return "/pages/secure/cotisation/paiement.xhtml?faces-redirect=true"; return ViewPaths.COTISATION_PAIEMENT + ".xhtml" + ViewPaths.REDIRECT_SUFFIX;
} }
public void actualiser() { public void actualiser() {

View File

@@ -1,5 +1,6 @@
package dev.lions.unionflow.client.view; package dev.lions.unionflow.client.view;
import dev.lions.unionflow.client.constants.ViewPaths;
import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.context.RequestScoped;
import jakarta.faces.context.FacesContext; import jakarta.faces.context.FacesContext;
import jakarta.inject.Inject; import jakarta.inject.Inject;
@@ -62,7 +63,7 @@ public class NavigationBean implements Serializable {
return redirectToLogin(); return redirectToLogin();
} }
return "/pages/secure/profile?faces-redirect=true"; return ViewPaths.PROFILE + ViewPaths.REDIRECT_SUFFIX;
} }
public String goToSettings() { public String goToSettings() {
@@ -71,11 +72,11 @@ public class NavigationBean implements Serializable {
} }
if (userSession.isSuperAdmin()) { if (userSession.isSuperAdmin()) {
return "/pages/super-admin/configuration/systeme?faces-redirect=true"; return ViewPaths.SUPER_ADMIN_CONFIGURATION_SYSTEME + ViewPaths.REDIRECT_SUFFIX;
} else if (userSession.isAdmin()) { } else if (userSession.isAdmin()) {
return "/pages/admin/parametres?faces-redirect=true"; return ViewPaths.ADMIN_PARAMETRES + ViewPaths.REDIRECT_SUFFIX;
} else { } else {
return "/pages/membre/parametres?faces-redirect=true"; return ViewPaths.MEMBRE_PARAMETRES + ViewPaths.REDIRECT_SUFFIX;
} }
} }
@@ -87,23 +88,21 @@ public class NavigationBean implements Serializable {
private String getDashboardUrlForUserType() { private String getDashboardUrlForUserType() {
if (userSession == null || userSession.getTypeCompte() == null) { if (userSession == null || userSession.getTypeCompte() == null) {
return "/pages/secure/dashboard.xhtml"; return ViewPaths.DASHBOARD + ".xhtml";
} }
switch (userSession.getTypeCompte()) { switch (userSession.getTypeCompte()) {
case "SUPER_ADMIN": case "SUPER_ADMIN":
return "/pages/super-admin/dashboard.xhtml"; return ViewPaths.SUPER_ADMIN_DASHBOARD + ".xhtml";
case "ADMIN_ORGANISATION": case "ADMIN_ORGANISATION":
return "/pages/secure/dashboard.xhtml";
case "MODERATEUR": case "MODERATEUR":
return "/pages/secure/dashboard.xhtml"; return ViewPaths.DASHBOARD + ".xhtml";
case "MEMBRE_ACTIF": case "MEMBRE_ACTIF":
return "/pages/secure/dashboard-membre.xhtml";
case "MEMBRE": case "MEMBRE":
return "/pages/secure/dashboard-membre.xhtml"; return ViewPaths.DASHBOARD_MEMBRE + ".xhtml";
default: default:
LOGGER.warning("Type de compte non reconnu: " + userSession.getTypeCompte()); LOGGER.warning("Type de compte non reconnu: " + userSession.getTypeCompte());
return "/pages/secure/dashboard.xhtml"; return ViewPaths.DASHBOARD + ".xhtml";
} }
} }

View File

@@ -1,6 +1,7 @@
package dev.lions.unionflow.client.view; package dev.lions.unionflow.client.view;
import dev.lions.unionflow.client.constants.StatutOrganisationConstants; import dev.lions.unionflow.client.constants.StatutOrganisationConstants;
import dev.lions.unionflow.client.constants.ViewPaths;
import dev.lions.unionflow.server.api.dto.organisation.response.OrganisationResponse; import dev.lions.unionflow.server.api.dto.organisation.response.OrganisationResponse;
import dev.lions.unionflow.server.api.dto.organisation.response.OrganisationSummaryResponse; import dev.lions.unionflow.server.api.dto.organisation.response.OrganisationSummaryResponse;
import dev.lions.unionflow.server.api.dto.common.PagedResponse; import dev.lions.unionflow.server.api.dto.common.PagedResponse;
@@ -245,7 +246,7 @@ public class OrganisationsBean implements Serializable {
chargerOrganisations(); chargerOrganisations();
chargerStatistiques(); chargerStatistiques();
return "/pages/secure/organisation/liste?faces-redirect=true"; return ViewPaths.ORGANISATION_LISTE + ViewPaths.REDIRECT_SUFFIX;
} catch (RestClientExceptionMapper.ConflictException e) { } catch (RestClientExceptionMapper.ConflictException e) {
errorHandler.handleException(e, "lors de la création d'une organisation", errorHandler.handleException(e, "lors de la création d'une organisation",

View File

@@ -0,0 +1,138 @@
package dev.lions.unionflow.client.view;
import dev.lions.unionflow.client.constants.ViewPaths;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Named;
import java.io.Serializable;
/**
* Bean exposant {@link ViewPaths} aux pages JSF via expressions EL.
*
* <p>Usage XHTML : {@code outcome="#{paths.uboList}"}.
*
* <p>Le bean est {@code @ApplicationScoped} car les chemins sont immuables et identiques pour
* tous les utilisateurs — un seul instance suffit.
*
* @since 2026-04-25 (Sprint 12)
*/
@Named("paths")
@ApplicationScoped
public class ViewPathsBean implements Serializable {
private static final long serialVersionUID = 1L;
// ─── Index / Dashboard ───────────────────────────────────────────────────
public String getRoot() { return ViewPaths.ROOT; }
public String getIndex() { return ViewPaths.INDEX; }
public String getDashboard() { return ViewPaths.DASHBOARD; }
public String getDashboardMembre() { return ViewPaths.DASHBOARD_MEMBRE; }
// ─── Profil personnel ────────────────────────────────────────────────────
public String getProfile() { return ViewPaths.PROFILE; }
public String getPersonnelProfil() { return ViewPaths.PERSONNEL_PROFIL; }
public String getPersonnelParametres() { return ViewPaths.PERSONNEL_PARAMETRES; }
public String getPersonnelPreferences() { return ViewPaths.PERSONNEL_PREFERENCES; }
public String getPersonnelNotifications() { return ViewPaths.PERSONNEL_NOTIFICATIONS; }
// ─── Membres ─────────────────────────────────────────────────────────────
public String getMembreListe() { return ViewPaths.MEMBRE_LISTE; }
public String getMembreInscription() { return ViewPaths.MEMBRE_INSCRIPTION; }
public String getMembreValidation() { return ViewPaths.MEMBRE_VALIDATION; }
public String getMembreImport() { return ViewPaths.MEMBRE_IMPORT; }
public String getMembreExport() { return ViewPaths.MEMBRE_EXPORT; }
public String getMembreRecherche() { return ViewPaths.MEMBRE_RECHERCHE; }
public String getMembreCotisations() { return ViewPaths.MEMBRE_COTISATIONS; }
public String getMembreProfil() { return ViewPaths.MEMBRE_PROFIL; }
public String getMembrePaiementCotisations() { return ViewPaths.MEMBRE_PAIEMENT_COTISATIONS; }
// ─── Adhésions ───────────────────────────────────────────────────────────
public String getAdhesionListe() { return ViewPaths.ADHESION_LISTE; }
public String getAdhesionDemande() { return ViewPaths.ADHESION_DEMANDE; }
public String getAdhesionValidation() { return ViewPaths.ADHESION_VALIDATION; }
public String getAdhesionHistorique() { return ViewPaths.ADHESION_HISTORIQUE; }
public String getAdhesionRenouvellement() { return ViewPaths.ADHESION_RENOUVELLEMENT; }
// ─── Cotisations ─────────────────────────────────────────────────────────
public String getCotisationsGestionAdmin() { return ViewPaths.COTISATIONS_GESTION_ADMIN; }
public String getCotisationPaiement() { return ViewPaths.COTISATION_PAIEMENT; }
public String getCotisationHistorique() { return ViewPaths.COTISATION_HISTORIQUE; }
public String getCotisationRelances() { return ViewPaths.COTISATION_RELANCES; }
// ─── Finance ─────────────────────────────────────────────────────────────
public String getFinanceTresorerie() { return ViewPaths.FINANCE_TRESORERIE; }
public String getFinanceBudgets() { return ViewPaths.FINANCE_BUDGETS; }
public String getFinanceBilans() { return ViewPaths.FINANCE_BILANS; }
public String getFinanceApprobations() { return ViewPaths.FINANCE_APPROBATIONS; }
public String getComptabiliteGestion() { return ViewPaths.COMPTABILITE_GESTION; }
// ─── Épargne / Crédit ────────────────────────────────────────────────────
public String getEpargneComptes() { return ViewPaths.EPARGNE_COMPTES; }
public String getCreditDemandes() { return ViewPaths.CREDIT_DEMANDES; }
public String getCreditEvaluation() { return ViewPaths.CREDIT_EVALUATION; }
public String getCreditSuivi() { return ViewPaths.CREDIT_SUIVI; }
public String getCreditRemboursements() { return ViewPaths.CREDIT_REMBOURSEMENTS; }
public String getCreditStatistiques() { return ViewPaths.CREDIT_STATISTIQUES; }
// ─── Événements ──────────────────────────────────────────────────────────
public String getEvenementGestion() { return ViewPaths.EVENEMENT_GESTION; }
public String getEvenementCreation() { return ViewPaths.EVENEMENT_CREATION; }
public String getEvenementCalendrier() { return ViewPaths.EVENEMENT_CALENDRIER; }
public String getEvenementParticipants() { return ViewPaths.EVENEMENT_PARTICIPANTS; }
public String getEvenementPlanification() { return ViewPaths.EVENEMENT_PLANIFICATION; }
public String getEvenementLogistique() { return ViewPaths.EVENEMENT_LOGISTIQUE; }
public String getEvenementBilan() { return ViewPaths.EVENEMENT_BILAN; }
public String getEvenementBilanDetail() { return ViewPaths.EVENEMENT_BILAN_DETAIL; }
// ─── Aide / Support ──────────────────────────────────────────────────────
public String getAideDemande() { return ViewPaths.AIDE_DEMANDE; }
public String getAideRequests() { return ViewPaths.AIDE_REQUESTS; }
public String getAideApproved() { return ViewPaths.AIDE_APPROVED; }
public String getAideTraitement() { return ViewPaths.AIDE_TRAITEMENT; }
public String getAideHistorique() { return ViewPaths.AIDE_HISTORIQUE; }
public String getAideStatistiques() { return ViewPaths.AIDE_STATISTIQUES; }
public String getAideFaq() { return ViewPaths.AIDE_FAQ; }
public String getAideSupport() { return ViewPaths.AIDE_SUPPORT; }
public String getAideApropos() { return ViewPaths.AIDE_APROPOS; }
// ─── Communication / Documents ───────────────────────────────────────────
public String getCommunicationConversations() { return ViewPaths.COMMUNICATION_CONVERSATIONS; }
public String getCommunicationNotifications() { return ViewPaths.COMMUNICATION_NOTIFICATIONS; }
public String getDocumentsMesDocuments() { return ViewPaths.DOCUMENTS_MES_DOCUMENTS; }
// ─── Organisation ────────────────────────────────────────────────────────
public String getOrganisationListe() { return ViewPaths.ORGANISATION_LISTE; }
public String getOrganisationDetail() { return ViewPaths.ORGANISATION_DETAIL; }
public String getOrganisationNouvelle() { return ViewPaths.ORGANISATION_NOUVELLE; }
public String getOrganisationStatistiques() { return ViewPaths.ORGANISATION_STATISTIQUES; }
// ─── Conformité (Sprints 8, 11) ──────────────────────────────────────────
public String getConformiteDashboard() { return ViewPaths.CONFORMITE_DASHBOARD; }
public String getConformiteRapportsTrimestriels() { return ViewPaths.CONFORMITE_RAPPORTS_TRIMESTRIELS; }
public String getConformiteBeneficiairesEffectifs() { return ViewPaths.CONFORMITE_BENEFICIAIRES_EFFECTIFS; }
public String getConformiteAuditTrail() { return ViewPaths.CONFORMITE_AUDIT_TRAIL; }
// ─── Admin technique ─────────────────────────────────────────────────────
public String getAdminPispiReadiness() { return ViewPaths.ADMIN_PISPI_READINESS; }
public String getAdminRoleDelegations() { return ViewPaths.ADMIN_ROLE_DELEGATIONS; }
public String getAdminSauvegarde() { return ViewPaths.ADMIN_SAUVEGARDE; }
public String getAdminAuditJournal() { return ViewPaths.ADMIN_AUDIT_JOURNAL; }
public String getAdminLogsSysteme() { return ViewPaths.ADMIN_LOGS_SYSTEME; }
public String getAdminParametres() { return ViewPaths.ADMIN_PARAMETRES; }
public String getMembreParametres() { return ViewPaths.MEMBRE_PARAMETRES; }
// ─── Rapports ────────────────────────────────────────────────────────────
public String getRapportFinances() { return ViewPaths.RAPPORT_FINANCES; }
public String getRapportMembres() { return ViewPaths.RAPPORT_MEMBRES; }
public String getRapportActivites() { return ViewPaths.RAPPORT_ACTIVITES; }
public String getRapportTableauxBord() { return ViewPaths.RAPPORT_TABLEAUX_BORD; }
public String getRapportExport() { return ViewPaths.RAPPORT_EXPORT; }
// ─── Souscription ────────────────────────────────────────────────────────
public String getSouscriptionDashboard() { return ViewPaths.SOUSCRIPTION_DASHBOARD; }
// ─── Super-Admin ─────────────────────────────────────────────────────────
public String getSuperAdminDashboard() { return ViewPaths.SUPER_ADMIN_DASHBOARD; }
public String getSuperAdminRolesGestion() { return ViewPaths.SUPER_ADMIN_ROLES_GESTION; }
public String getSuperAdminTypesOrganisations() { return ViewPaths.SUPER_ADMIN_TYPES_ORGANISATIONS; }
public String getSuperAdminConfigurationSysteme() { return ViewPaths.SUPER_ADMIN_CONFIGURATION_SYSTEME; }
}

View File

@@ -63,11 +63,11 @@
<h:form> <h:form>
<p:button value="Se reconnecter" <p:button value="Se reconnecter"
icon="pi pi-sign-in" icon="pi pi-sign-in"
outcome="/" outcome="#{paths.root}"
styleClass="ui-button-primary ui-button-lg" /> styleClass="ui-button-primary ui-button-lg" />
<p:button value="Page d'accueil" <p:button value="Page d'accueil"
icon="pi pi-home" icon="pi pi-home"
outcome="/index" outcome="#{paths.index}"
styleClass="ui-button-secondary ui-button-outlined ui-button-lg" /> styleClass="ui-button-secondary ui-button-outlined ui-button-lg" />
</h:form> </h:form>
</div> </div>

View File

@@ -32,7 +32,7 @@
<!-- Landing Topbar --> <!-- Landing Topbar -->
<div class="landing-topbar"> <div class="landing-topbar">
<div class="landing-topbar-left"> <div class="landing-topbar-left">
<h:link id="logolink" outcome="/pages/secure/dashboard" styleClass="logo unionflow-brand unionflow-brand--landing"> <h:link id="logolink" outcome="#{paths.dashboard}" styleClass="logo unionflow-brand unionflow-brand--landing">
<h:graphicImage value="#{request.contextPath}/resources/freya-layout/images/unionflow-logo.png" <h:graphicImage value="#{request.contextPath}/resources/freya-layout/images/unionflow-logo.png"
alt="Logo UnionFlow" alt="Logo UnionFlow"
styleClass="unionflow-brand-icon" /> styleClass="unionflow-brand-icon" />

View File

@@ -12,7 +12,7 @@
<div class="card"> <div class="card">
<h2>Administration - Audit</h2> <h2>Administration - Audit</h2>
<p>Page d'administration en cours de développement...</p> <p>Page d'administration en cours de développement...</p>
<p:button value="Retour" icon="pi pi-arrow-left" outcome="/pages/secure/dashboard"/> <p:button value="Retour" icon="pi pi-arrow-left" outcome="#{paths.dashboard}"/>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -12,7 +12,7 @@
<div class="card"> <div class="card">
<h2>Administration - Backup</h2> <h2>Administration - Backup</h2>
<p>Page d'administration en cours de développement...</p> <p>Page d'administration en cours de développement...</p>
<p:button value="Retour" icon="pi pi-arrow-left" outcome="/pages/secure/dashboard"/> <p:button value="Retour" icon="pi pi-arrow-left" outcome="#{paths.dashboard}"/>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -12,7 +12,7 @@
<div class="card"> <div class="card">
<h2>Administration - Settings</h2> <h2>Administration - Settings</h2>
<p>Page d'administration en cours de développement...</p> <p>Page d'administration en cours de développement...</p>
<p:button value="Retour" icon="pi pi-arrow-left" outcome="/pages/secure/dashboard"/> <p:button value="Retour" icon="pi pi-arrow-left" outcome="#{paths.dashboard}"/>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -12,7 +12,7 @@
<div class="card"> <div class="card">
<h2>Administration - Users</h2> <h2>Administration - Users</h2>
<p>Page d'administration en cours de développement...</p> <p>Page d'administration en cours de développement...</p>
<p:button value="Retour" icon="pi pi-arrow-left" outcome="/pages/secure/dashboard"/> <p:button value="Retour" icon="pi pi-arrow-left" outcome="#{paths.dashboard}"/>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -170,7 +170,7 @@
<p:commandButton value="Voir bilan" <p:commandButton value="Voir bilan"
icon="pi pi-chart-bar" icon="pi pi-chart-bar"
styleClass="ui-button-rounded ui-button-text ui-button-secondary" styleClass="ui-button-rounded ui-button-text ui-button-secondary"
outcome="/pages/secure/evenement/bilan-detail" /> outcome="#{paths.evenementBilanDetail}" />
</p:column> </p:column>
</p:dataTable> </p:dataTable>
</h:form> </h:form>

View File

@@ -168,7 +168,7 @@
<div class="flex gap-2"> <div class="flex gap-2">
<p:commandButton value="Voir détails" <p:commandButton value="Voir détails"
icon="pi pi-eye" icon="pi pi-eye"
outcome="/pages/secure/evenement/gestion.xhtml" outcome="#{paths.evenementGestion}"
styleClass="p-button-outlined" /> styleClass="p-button-outlined" />
<p:commandButton value="Fermer" <p:commandButton value="Fermer"
icon="pi pi-times" icon="pi pi-times"

View File

@@ -616,7 +616,7 @@
</div> </div>
<div style="font-weight:700;color:var(--text-color);"> <div style="font-weight:700;color:var(--text-color);">
<h:link value="#{organisationDetailBean.organisation.organisationParenteNom}" <h:link value="#{organisationDetailBean.organisation.organisationParenteNom}"
outcome="/pages/secure/organisation/detail" outcome="#{paths.organisationDetail}"
styleClass="text-cyan-700 font-bold no-underline hover:underline"> styleClass="text-cyan-700 font-bold no-underline hover:underline">
<f:param name="id" value="#{organisationDetailBean.organisation.organisationParenteId}" /> <f:param name="id" value="#{organisationDetailBean.organisation.organisationParenteId}" />
</h:link> </h:link>

View File

@@ -38,7 +38,7 @@
<p:button value="Nouvelle organisation" <p:button value="Nouvelle organisation"
icon="pi pi-plus" icon="pi pi-plus"
styleClass="ui-button-success" styleClass="ui-button-success"
outcome="/pages/secure/organisation/nouvelle" /> outcome="#{paths.organisationNouvelle}" />
</div> </div>
</div> </div>
</div> </div>

View File

@@ -17,7 +17,7 @@
<p:button value="Retour au tableau de bord" <p:button value="Retour au tableau de bord"
icon="pi pi-arrow-left" icon="pi pi-arrow-left"
outcome="/pages/secure/dashboard"/> outcome="#{paths.dashboard}"/>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -28,37 +28,37 @@
<!-- ════════════════════════════════════════════════════════ --> <!-- ════════════════════════════════════════════════════════ -->
<!-- TABLEAU DE BORD --> <!-- TABLEAU DE BORD -->
<!-- ════════════════════════════════════════════════════════ --> <!-- ════════════════════════════════════════════════════════ -->
<p:menuitem id="m_dashboard" value="Tableau de Bord" icon="pi pi-home" outcome="/pages/secure/dashboard" /> <p:menuitem id="m_dashboard" value="Tableau de Bord" icon="pi pi-home" outcome="#{paths.dashboard}" />
<!-- ════════════════════════════════════════════════════════ --> <!-- ════════════════════════════════════════════════════════ -->
<!-- SUPER ADMINISTRATION (SUPER_ADMIN uniquement) --> <!-- SUPER ADMINISTRATION (SUPER_ADMIN uniquement) -->
<!-- ════════════════════════════════════════════════════════ --> <!-- ════════════════════════════════════════════════════════ -->
<p:submenu id="m_super_admin" label="Super Administration" icon="pi pi-shield" rendered="#{menuBean.superAdminMenuVisible}"> <p:submenu id="m_super_admin" label="Super Administration" icon="pi pi-shield" rendered="#{menuBean.superAdminMenuVisible}">
<p:menuitem id="m_super_dashboard" value="Dashboard Super-Admin" icon="pi pi-chart-bar" outcome="/pages/super-admin/dashboard" /> <p:menuitem id="m_super_dashboard" value="Dashboard Super-Admin" icon="pi pi-chart-bar" outcome="#{paths.superAdminDashboard}" />
<p:menuitem id="m_roles" value="Rôles Applicatifs" icon="pi pi-key" outcome="/pages/super-admin/roles/gestion" /> <p:menuitem id="m_roles" value="Rôles Applicatifs" icon="pi pi-key" outcome="#{paths.superAdminRolesGestion}" />
<p:menuitem id="m_audit" value="Journal d'Audit" icon="pi pi-file-o" outcome="/pages/admin/audit/journal" /> <p:menuitem id="m_audit" value="Journal d'Audit" icon="pi pi-file-o" outcome="#{paths.adminAuditJournal}" />
<p:menuitem id="m_logs_systeme" value="Logs Système" icon="pi pi-list" outcome="/pages/admin/logs/systeme" /> <p:menuitem id="m_logs_systeme" value="Logs Système" icon="pi pi-list" outcome="#{paths.adminLogsSysteme}" />
<p:menuitem id="m_sauvegardes" value="Sauvegardes" icon="pi pi-save" outcome="/pages/secure/admin/sauvegarde" /> <p:menuitem id="m_sauvegardes" value="Sauvegardes" icon="pi pi-save" outcome="#{paths.adminSauvegarde}" />
<p:menuitem id="m_config_systeme" value="Configuration Système" icon="pi pi-cog" outcome="/pages/super-admin/configuration/systeme" /> <p:menuitem id="m_config_systeme" value="Configuration Système" icon="pi pi-cog" outcome="#{paths.superAdminConfigurationSysteme}" />
</p:submenu> </p:submenu>
<!-- ════════════════════════════════════════════════════════ --> <!-- ════════════════════════════════════════════════════════ -->
<!-- ORGANISATIONS --> <!-- ORGANISATIONS -->
<!-- ════════════════════════════════════════════════════════ --> <!-- ════════════════════════════════════════════════════════ -->
<p:submenu id="m_organisations" label="Organisations" icon="pi pi-building" rendered="#{menuBean.superAdmin}"> <p:submenu id="m_organisations" label="Organisations" icon="pi pi-building" rendered="#{menuBean.superAdmin}">
<p:menuitem id="m_liste_organisations" value="Liste des Organisations" icon="pi pi-list" outcome="/pages/secure/organisation/liste" /> <p:menuitem id="m_liste_organisations" value="Liste des Organisations" icon="pi pi-list" outcome="#{paths.organisationListe}" />
<p:menuitem id="m_nouvelle_organisation" value="Nouvelle Organisation" icon="pi pi-plus" outcome="/pages/secure/organisation/nouvelle" /> <p:menuitem id="m_nouvelle_organisation" value="Nouvelle Organisation" icon="pi pi-plus" outcome="#{paths.organisationNouvelle}" />
<p:menuitem id="m_statistiques_orga" value="Statistiques" icon="pi pi-chart-bar" outcome="/pages/secure/organisation/statistiques" /> <p:menuitem id="m_statistiques_orga" value="Statistiques" icon="pi pi-chart-bar" outcome="#{paths.organisationStatistiques}" />
<p:menuitem id="m_types_organisations" value="Types d'Organisation" icon="pi pi-tags" outcome="/pages/super-admin/types/organisations" /> <p:menuitem id="m_types_organisations" value="Types d'Organisation" icon="pi pi-tags" outcome="#{paths.superAdminTypesOrganisations}" />
</p:submenu> </p:submenu>
<p:submenu id="m_mon_organisation" label="Mon Organisation" icon="pi pi-building" rendered="#{menuBean.adminOrganisation and not menuBean.superAdmin}"> <p:submenu id="m_mon_organisation" label="Mon Organisation" icon="pi pi-building" rendered="#{menuBean.adminOrganisation and not menuBean.superAdmin}">
<p:menuitem id="m_detail_organisation" value="Détail &amp; Paramètres" icon="pi pi-building" <p:menuitem id="m_detail_organisation" value="Détail &amp; Paramètres" icon="pi pi-building"
outcome="/pages/secure/organisation/detail"> outcome="#{paths.organisationDetail}">
<f:param name="id" value="#{userSession.activeOrganisationId}" /> <f:param name="id" value="#{userSession.activeOrganisationId}" />
</p:menuitem> </p:menuitem>
<p:menuitem id="m_mon_abonnement" value="Mon Abonnement" icon="pi pi-credit-card" <p:menuitem id="m_mon_abonnement" value="Mon Abonnement" icon="pi pi-credit-card"
outcome="/pages/secure/souscription/dashboard" /> outcome="#{paths.souscriptionDashboard}" />
</p:submenu> </p:submenu>
<!-- ════════════════════════════════════════════════════════ --> <!-- ════════════════════════════════════════════════════════ -->
@@ -66,76 +66,76 @@
<!-- Un seul sous-menu, items conditionnels par rôle --> <!-- Un seul sous-menu, items conditionnels par rôle -->
<!-- ════════════════════════════════════════════════════════ --> <!-- ════════════════════════════════════════════════════════ -->
<p:submenu id="m_membres" label="Membres" icon="pi pi-users" rendered="#{menuBean.annuaireMembresVisible}"> <p:submenu id="m_membres" label="Membres" icon="pi pi-users" rendered="#{menuBean.annuaireMembresVisible}">
<p:menuitem id="m_liste_membres" value="Annuaire des Membres" icon="pi pi-list" outcome="/pages/secure/membre/liste" /> <p:menuitem id="m_liste_membres" value="Annuaire des Membres" icon="pi pi-list" outcome="#{paths.membreListe}" />
<p:menuitem id="m_recherche_membres" value="Rechercher un Membre" icon="pi pi-search" outcome="/pages/secure/membre/recherche" /> <p:menuitem id="m_recherche_membres" value="Rechercher un Membre" icon="pi pi-search" outcome="#{paths.membreRecherche}" />
<p:menuitem id="m_inscription" value="Nouvelle Inscription" icon="pi pi-user-plus" outcome="/pages/secure/membre/inscription" rendered="#{menuBean.gestionMembresMenuVisible}" /> <p:menuitem id="m_inscription" value="Nouvelle Inscription" icon="pi pi-user-plus" outcome="#{paths.membreInscription}" rendered="#{menuBean.gestionMembresMenuVisible}" />
<p:menuitem id="m_validation_membres" value="Validation Inscriptions" icon="pi pi-check-circle" outcome="/pages/secure/membre/validation" rendered="#{menuBean.gestionMembresMenuVisible}" /> <p:menuitem id="m_validation_membres" value="Validation Inscriptions" icon="pi pi-check-circle" outcome="#{paths.membreValidation}" rendered="#{menuBean.gestionMembresMenuVisible}" />
<p:menuitem id="m_import_membres" value="Import en Masse" icon="pi pi-upload" outcome="/pages/secure/membre/import" rendered="#{menuBean.gestionMembresMenuVisible}" /> <p:menuitem id="m_import_membres" value="Import en Masse" icon="pi pi-upload" outcome="#{paths.membreImport}" rendered="#{menuBean.gestionMembresMenuVisible}" />
<p:menuitem id="m_export_membres" value="Export Membres" icon="pi pi-download" outcome="/pages/secure/membre/export" rendered="#{menuBean.gestionMembresMenuVisible}" /> <p:menuitem id="m_export_membres" value="Export Membres" icon="pi pi-download" outcome="#{paths.membreExport}" rendered="#{menuBean.gestionMembresMenuVisible}" />
</p:submenu> </p:submenu>
<!-- ════════════════════════════════════════════════════════ --> <!-- ════════════════════════════════════════════════════════ -->
<!-- ADHÉSIONS --> <!-- ADHÉSIONS -->
<!-- ════════════════════════════════════════════════════════ --> <!-- ════════════════════════════════════════════════════════ -->
<p:submenu id="m_adhesions" label="Adhésions" icon="pi pi-bookmark" rendered="#{menuBean.adhesionsMenuVisible}"> <p:submenu id="m_adhesions" label="Adhésions" icon="pi pi-bookmark" rendered="#{menuBean.adhesionsMenuVisible}">
<p:menuitem id="m_demande_adhesion" value="Nouvelle Demande" icon="pi pi-plus-circle" outcome="/pages/secure/adhesion/demande" /> <p:menuitem id="m_demande_adhesion" value="Nouvelle Demande" icon="pi pi-plus-circle" outcome="#{paths.adhesionDemande}" />
<p:menuitem id="m_liste_adhesions" value="Toutes les Adhésions" icon="pi pi-list" outcome="/pages/secure/adhesion/liste" /> <p:menuitem id="m_liste_adhesions" value="Toutes les Adhésions" icon="pi pi-list" outcome="#{paths.adhesionListe}" />
<p:menuitem id="m_validation_adhesion" value="Validation des Demandes" icon="pi pi-check-circle" outcome="/pages/secure/adhesion/validation" rendered="#{menuBean.validationAdhesionVisible}" /> <p:menuitem id="m_validation_adhesion" value="Validation des Demandes" icon="pi pi-check-circle" outcome="#{paths.adhesionValidation}" rendered="#{menuBean.validationAdhesionVisible}" />
<p:menuitem id="m_renouvellement" value="Renouvellements" icon="pi pi-refresh" outcome="/pages/secure/adhesion/renouvellement" /> <p:menuitem id="m_renouvellement" value="Renouvellements" icon="pi pi-refresh" outcome="#{paths.adhesionRenouvellement}" />
<p:menuitem id="m_historique_adhesions" value="Historique" icon="pi pi-history" outcome="/pages/secure/adhesion/historique" /> <p:menuitem id="m_historique_adhesions" value="Historique" icon="pi pi-history" outcome="#{paths.adhesionHistorique}" />
</p:submenu> </p:submenu>
<!-- ════════════════════════════════════════════════════════ --> <!-- ════════════════════════════════════════════════════════ -->
<!-- MES FINANCES (perso — tous les membres) --> <!-- MES FINANCES (perso — tous les membres) -->
<!-- ════════════════════════════════════════════════════════ --> <!-- ════════════════════════════════════════════════════════ -->
<p:submenu id="m_mes_finances" label="Mes Finances" icon="pi pi-wallet" rendered="#{menuBean.mesFinancesMenuVisible}"> <p:submenu id="m_mes_finances" label="Mes Finances" icon="pi pi-wallet" rendered="#{menuBean.mesFinancesMenuVisible}">
<p:menuitem id="m_mes_cotisations" value="Mes Cotisations" icon="pi pi-credit-card" outcome="/pages/secure/membre/cotisations" /> <p:menuitem id="m_mes_cotisations" value="Mes Cotisations" icon="pi pi-credit-card" outcome="#{paths.membreCotisations}" />
<p:menuitem id="m_payer_cotisations" value="Payer mes Cotisations" icon="pi pi-dollar" outcome="/pages/secure/cotisation/paiement" /> <p:menuitem id="m_payer_cotisations" value="Payer mes Cotisations" icon="pi pi-dollar" outcome="#{paths.cotisationPaiement}" />
<p:menuitem id="m_historique_finances" value="Historique" icon="pi pi-history" outcome="/pages/secure/cotisation/historique" /> <p:menuitem id="m_historique_finances" value="Historique" icon="pi pi-history" outcome="#{paths.cotisationHistorique}" />
</p:submenu> </p:submenu>
<!-- ════════════════════════════════════════════════════════ --> <!-- ════════════════════════════════════════════════════════ -->
<!-- GESTION FINANCIÈRE (admin — trésorier, admin org) --> <!-- GESTION FINANCIÈRE (admin — trésorier, admin org) -->
<!-- ════════════════════════════════════════════════════════ --> <!-- ════════════════════════════════════════════════════════ -->
<p:submenu id="m_gestion_finances" label="Gestion Financière" icon="pi pi-dollar" rendered="#{menuBean.gestionFinancesMenuVisible}"> <p:submenu id="m_gestion_finances" label="Gestion Financière" icon="pi pi-dollar" rendered="#{menuBean.gestionFinancesMenuVisible}">
<p:menuitem id="m_gestion_cotisations" value="Gestion Cotisations" icon="pi pi-dollar" outcome="/pages/admin/cotisations/gestion" /> <p:menuitem id="m_gestion_cotisations" value="Gestion Cotisations" icon="pi pi-dollar" outcome="#{paths.cotisationsGestionAdmin}" />
<p:menuitem id="m_tresorerie" value="Trésorerie" icon="pi pi-wallet" outcome="/pages/secure/finance/tresorerie" /> <p:menuitem id="m_tresorerie" value="Trésorerie" icon="pi pi-wallet" outcome="#{paths.financeTresorerie}" />
<p:menuitem id="m_budgets" value="Gestion des Budgets" icon="pi pi-chart-pie" outcome="/pages/secure/finance/budgets" /> <p:menuitem id="m_budgets" value="Gestion des Budgets" icon="pi pi-chart-pie" outcome="#{paths.financeBudgets}" />
<p:menuitem id="m_approbations_finance" value="Approbations" icon="pi pi-check-square" outcome="/pages/secure/finance/approbations" /> <p:menuitem id="m_approbations_finance" value="Approbations" icon="pi pi-check-square" outcome="#{paths.financeApprobations}" />
<p:menuitem id="m_comptabilite" value="Comptabilité" icon="pi pi-calculator" outcome="/pages/secure/comptabilite/gestion" /> <p:menuitem id="m_comptabilite" value="Comptabilité" icon="pi pi-calculator" outcome="#{paths.comptabiliteGestion}" />
<p:menuitem id="m_relances" value="Relances Cotisations" icon="pi pi-bell" outcome="/pages/secure/cotisation/relances" /> <p:menuitem id="m_relances" value="Relances Cotisations" icon="pi pi-bell" outcome="#{paths.cotisationRelances}" />
<p:menuitem id="m_bilans" value="Bilans Financiers" icon="pi pi-chart-line" outcome="/pages/secure/finance/bilans" /> <p:menuitem id="m_bilans" value="Bilans Financiers" icon="pi pi-chart-line" outcome="#{paths.financeBilans}" />
</p:submenu> </p:submenu>
<!-- ════════════════════════════════════════════════════════ --> <!-- ════════════════════════════════════════════════════════ -->
<!-- CONFORMITÉ (Sprint 8 — BCEAO / ARTCI / OHADA) --> <!-- CONFORMITÉ (Sprint 8 — BCEAO / ARTCI / OHADA) -->
<!-- ════════════════════════════════════════════════════════ --> <!-- ════════════════════════════════════════════════════════ -->
<p:submenu id="m_conformite" label="Conformité" icon="pi pi-verified" rendered="#{menuBean.conformiteDashboardVisible}"> <p:submenu id="m_conformite" label="Conformité" icon="pi pi-verified" rendered="#{menuBean.conformiteDashboardVisible}">
<p:menuitem id="m_conformite_dashboard" value="Tableau de bord" icon="pi pi-chart-bar" outcome="/pages/secure/conformite/dashboard" /> <p:menuitem id="m_conformite_dashboard" value="Tableau de bord" icon="pi pi-chart-bar" outcome="#{paths.conformiteDashboard}" />
<p:menuitem id="m_rapports_trimestriels" value="Rapports trimestriels" icon="pi pi-file-pdf" outcome="/pages/secure/conformite/rapports-trimestriels" rendered="#{menuBean.rapportsTrimestrielsVisible}" /> <p:menuitem id="m_rapports_trimestriels" value="Rapports trimestriels" icon="pi pi-file-pdf" outcome="#{paths.conformiteRapportsTrimestriels}" rendered="#{menuBean.rapportsTrimestrielsVisible}" />
<p:menuitem id="m_ubo" value="Bénéficiaires Effectifs" icon="pi pi-users" outcome="/pages/secure/conformite/beneficiaires-effectifs" rendered="#{menuBean.beneficiairesEffectifsVisible}" /> <p:menuitem id="m_ubo" value="Bénéficiaires Effectifs" icon="pi pi-users" outcome="#{paths.conformiteBeneficiairesEffectifs}" rendered="#{menuBean.beneficiairesEffectifsVisible}" />
<p:menuitem id="m_audit_trail" value="Audit Trail" icon="pi pi-history" outcome="/pages/secure/conformite/audit-trail" rendered="#{menuBean.auditTrailViewerVisible}" /> <p:menuitem id="m_audit_trail" value="Audit Trail" icon="pi pi-history" outcome="#{paths.conformiteAuditTrail}" rendered="#{menuBean.auditTrailViewerVisible}" />
<p:menuitem id="m_role_delegations" value="Délégations de rôles" icon="pi pi-share-alt" outcome="/pages/secure/admin/role-delegations" rendered="#{menuBean.roleDelegationsVisible}" /> <p:menuitem id="m_role_delegations" value="Délégations de rôles" icon="pi pi-share-alt" outcome="#{paths.adminRoleDelegations}" rendered="#{menuBean.roleDelegationsVisible}" />
<p:menuitem id="m_pispi_readiness" value="PI-SPI Readiness" icon="pi pi-cog" outcome="/pages/secure/admin/pispi-readiness" rendered="#{menuBean.pispiReadinessVisible}" /> <p:menuitem id="m_pispi_readiness" value="PI-SPI Readiness" icon="pi pi-cog" outcome="#{paths.adminPispiReadiness}" rendered="#{menuBean.pispiReadinessVisible}" />
</p:submenu> </p:submenu>
<!-- ════════════════════════════════════════════════════════ --> <!-- ════════════════════════════════════════════════════════ -->
<!-- ÉPARGNE (module EPARGNE — mutuelle, coopérative) --> <!-- ÉPARGNE (module EPARGNE — mutuelle, coopérative) -->
<!-- ════════════════════════════════════════════════════════ --> <!-- ════════════════════════════════════════════════════════ -->
<p:submenu id="m_epargne" label="Épargne &amp; Crédit" icon="pi pi-wallet" rendered="#{menuBean.epargneMenuVisible}"> <p:submenu id="m_epargne" label="Épargne &amp; Crédit" icon="pi pi-wallet" rendered="#{menuBean.epargneMenuVisible}">
<p:menuitem id="m_epargne_comptes" value="Comptes Épargne" icon="pi pi-wallet" outcome="/pages/secure/epargne/comptes" /> <p:menuitem id="m_epargne_comptes" value="Comptes Épargne" icon="pi pi-wallet" outcome="#{paths.epargneComptes}" />
<p:menuitem id="m_demandes_credit" value="Demandes de Crédit" icon="pi pi-inbox" outcome="/pages/secure/credit/demandes" rendered="#{menuBean.creditMenuVisible}" /> <p:menuitem id="m_demandes_credit" value="Demandes de Crédit" icon="pi pi-inbox" outcome="#{paths.creditDemandes}" rendered="#{menuBean.creditMenuVisible}" />
<p:menuitem id="m_evaluation_credit" value="Évaluation Solvabilité" icon="pi pi-search" outcome="/pages/secure/credit/evaluation" rendered="#{menuBean.creditMenuVisible}" /> <p:menuitem id="m_evaluation_credit" value="Évaluation Solvabilité" icon="pi pi-search" outcome="#{paths.creditEvaluation}" rendered="#{menuBean.creditMenuVisible}" />
<p:menuitem id="m_suivi_credits" value="Suivi des Crédits" icon="pi pi-eye" outcome="/pages/secure/credit/suivi" rendered="#{menuBean.creditMenuVisible}" /> <p:menuitem id="m_suivi_credits" value="Suivi des Crédits" icon="pi pi-eye" outcome="#{paths.creditSuivi}" rendered="#{menuBean.creditMenuVisible}" />
<p:menuitem id="m_remboursements" value="Remboursements" icon="pi pi-replay" outcome="/pages/secure/credit/remboursements" rendered="#{menuBean.creditMenuVisible}" /> <p:menuitem id="m_remboursements" value="Remboursements" icon="pi pi-replay" outcome="#{paths.creditRemboursements}" rendered="#{menuBean.creditMenuVisible}" />
<p:menuitem id="m_stats_credit" value="Statistiques Crédit" icon="pi pi-chart-bar" outcome="/pages/secure/credit/statistiques" rendered="#{menuBean.creditMenuVisible}" /> <p:menuitem id="m_stats_credit" value="Statistiques Crédit" icon="pi pi-chart-bar" outcome="#{paths.creditStatistiques}" rendered="#{menuBean.creditMenuVisible}" />
</p:submenu> </p:submenu>
<!-- Mon Épargne (membre — visible si pas admin épargne) --> <!-- Mon Épargne (membre — visible si pas admin épargne) -->
<p:submenu id="m_mon_epargne" label="Mon Épargne" icon="pi pi-wallet" rendered="#{menuBean.epargneMemberVisible and not menuBean.epargneMenuVisible}"> <p:submenu id="m_mon_epargne" label="Mon Épargne" icon="pi pi-wallet" rendered="#{menuBean.epargneMemberVisible and not menuBean.epargneMenuVisible}">
<p:menuitem id="m_mon_epargne_compte" value="Mon Compte Épargne" icon="pi pi-wallet" outcome="/pages/secure/epargne/comptes" /> <p:menuitem id="m_mon_epargne_compte" value="Mon Compte Épargne" icon="pi pi-wallet" outcome="#{paths.epargneComptes}" />
<p:menuitem id="m_demande_pret" value="Demander un Prêt" icon="pi pi-plus" outcome="/pages/secure/credit/demandes" rendered="#{menuBean.creditMemberVisible}" /> <p:menuitem id="m_demande_pret" value="Demander un Prêt" icon="pi pi-plus" outcome="#{paths.creditDemandes}" rendered="#{menuBean.creditMemberVisible}" />
<p:menuitem id="m_mes_credits" value="Mes Crédits en Cours" icon="pi pi-list" outcome="/pages/secure/credit/suivi" rendered="#{menuBean.creditMemberVisible}" /> <p:menuitem id="m_mes_credits" value="Mes Crédits en Cours" icon="pi pi-list" outcome="#{paths.creditSuivi}" rendered="#{menuBean.creditMemberVisible}" />
</p:submenu> </p:submenu>
<!-- ════════════════════════════════════════════════════════ --> <!-- ════════════════════════════════════════════════════════ -->
@@ -175,70 +175,70 @@
<!-- AIDE SOCIALE --> <!-- AIDE SOCIALE -->
<!-- ════════════════════════════════════════════════════════ --> <!-- ════════════════════════════════════════════════════════ -->
<p:submenu id="m_mes_aides" label="Aide Sociale" icon="pi pi-heart" rendered="#{menuBean.mesAidesSocialesMenuVisible}"> <p:submenu id="m_mes_aides" label="Aide Sociale" icon="pi pi-heart" rendered="#{menuBean.mesAidesSocialesMenuVisible}">
<p:menuitem id="m_demande_aide" value="Faire une Demande" icon="pi pi-plus" outcome="/pages/secure/aide/demande" /> <p:menuitem id="m_demande_aide" value="Faire une Demande" icon="pi pi-plus" outcome="#{paths.aideDemande}" />
<p:menuitem id="m_mes_demandes_aide" value="Mes Demandes" icon="pi pi-list" outcome="/pages/secure/aide/requests" /> <p:menuitem id="m_mes_demandes_aide" value="Mes Demandes" icon="pi pi-list" outcome="#{paths.aideRequests}" />
<p:menuitem id="m_historique_aides" value="Historique" icon="pi pi-clock" outcome="/pages/secure/aide/historique" /> <p:menuitem id="m_historique_aides" value="Historique" icon="pi pi-clock" outcome="#{paths.aideHistorique}" />
<p:menuitem id="m_traitement_aide" value="Traitement des Demandes" icon="pi pi-cog" outcome="/pages/secure/aide/traitement" rendered="#{menuBean.gestionAidesSocialesMenuVisible}" /> <p:menuitem id="m_traitement_aide" value="Traitement des Demandes" icon="pi pi-cog" outcome="#{paths.aideTraitement}" rendered="#{menuBean.gestionAidesSocialesMenuVisible}" />
<p:menuitem id="m_suivi_aide" value="Suivi des Bénéficiaires" icon="pi pi-eye" outcome="/pages/secure/aide/approved" rendered="#{menuBean.gestionAidesSocialesMenuVisible}" /> <p:menuitem id="m_suivi_aide" value="Suivi des Bénéficiaires" icon="pi pi-eye" outcome="#{paths.aideApproved}" rendered="#{menuBean.gestionAidesSocialesMenuVisible}" />
<p:menuitem id="m_statistiques_aides" value="Statistiques Sociales" icon="pi pi-chart-line" outcome="/pages/secure/aide/statistiques" rendered="#{menuBean.gestionAidesSocialesMenuVisible}" /> <p:menuitem id="m_statistiques_aides" value="Statistiques Sociales" icon="pi pi-chart-line" outcome="#{paths.aideStatistiques}" rendered="#{menuBean.gestionAidesSocialesMenuVisible}" />
</p:submenu> </p:submenu>
<!-- ════════════════════════════════════════════════════════ --> <!-- ════════════════════════════════════════════════════════ -->
<!-- ÉVÉNEMENTS --> <!-- ÉVÉNEMENTS -->
<!-- ════════════════════════════════════════════════════════ --> <!-- ════════════════════════════════════════════════════════ -->
<p:submenu id="m_evenements" label="Événements" icon="pi pi-calendar" rendered="#{menuBean.mesEvenementsMenuVisible}"> <p:submenu id="m_evenements" label="Événements" icon="pi pi-calendar" rendered="#{menuBean.mesEvenementsMenuVisible}">
<p:menuitem id="m_calendrier" value="Calendrier" icon="pi pi-calendar-plus" outcome="/pages/secure/evenement/calendrier" /> <p:menuitem id="m_calendrier" value="Calendrier" icon="pi pi-calendar-plus" outcome="#{paths.evenementCalendrier}" />
<p:menuitem id="m_mes_inscriptions_events" value="Mes Inscriptions" icon="pi pi-list" outcome="/pages/secure/evenement/participants" /> <p:menuitem id="m_mes_inscriptions_events" value="Mes Inscriptions" icon="pi pi-list" outcome="#{paths.evenementParticipants}" />
<p:menuitem id="m_creation_evenement" value="Nouvel Événement" icon="pi pi-plus" outcome="/pages/secure/evenement/creation" rendered="#{menuBean.gestionEvenementsMenuVisible}" /> <p:menuitem id="m_creation_evenement" value="Nouvel Événement" icon="pi pi-plus" outcome="#{paths.evenementCreation}" rendered="#{menuBean.gestionEvenementsMenuVisible}" />
<p:menuitem id="m_planification" value="Planification" icon="pi pi-clock" outcome="/pages/secure/evenement/planification" rendered="#{menuBean.gestionEvenementsMenuVisible}" /> <p:menuitem id="m_planification" value="Planification" icon="pi pi-clock" outcome="#{paths.evenementPlanification}" rendered="#{menuBean.gestionEvenementsMenuVisible}" />
<p:menuitem id="m_logistique" value="Logistique" icon="pi pi-truck" outcome="/pages/secure/evenement/logistique" rendered="#{menuBean.gestionEvenementsMenuVisible}" /> <p:menuitem id="m_logistique" value="Logistique" icon="pi pi-truck" outcome="#{paths.evenementLogistique}" rendered="#{menuBean.gestionEvenementsMenuVisible}" />
<p:menuitem id="m_gestion_generale_evenements" value="Gestion Générale" icon="pi pi-cog" outcome="/pages/secure/evenement/gestion" rendered="#{menuBean.gestionEvenementsMenuVisible}" /> <p:menuitem id="m_gestion_generale_evenements" value="Gestion Générale" icon="pi pi-cog" outcome="#{paths.evenementGestion}" rendered="#{menuBean.gestionEvenementsMenuVisible}" />
<p:menuitem id="m_bilan_evenements" value="Bilans" icon="pi pi-chart-bar" outcome="/pages/secure/evenement/bilan" rendered="#{menuBean.gestionEvenementsMenuVisible}" /> <p:menuitem id="m_bilan_evenements" value="Bilans" icon="pi pi-chart-bar" outcome="#{paths.evenementBilan}" rendered="#{menuBean.gestionEvenementsMenuVisible}" />
</p:submenu> </p:submenu>
<!-- ════════════════════════════════════════════════════════ --> <!-- ════════════════════════════════════════════════════════ -->
<!-- COMMUNICATION --> <!-- COMMUNICATION -->
<!-- ════════════════════════════════════════════════════════ --> <!-- ════════════════════════════════════════════════════════ -->
<p:submenu id="m_communications" label="Communication" icon="pi pi-envelope" rendered="#{menuBean.mesCommunicationsMenuVisible}"> <p:submenu id="m_communications" label="Communication" icon="pi pi-envelope" rendered="#{menuBean.mesCommunicationsMenuVisible}">
<p:menuitem id="m_messagerie" value="Messagerie" icon="pi pi-comments" outcome="/pages/secure/communication/conversations" /> <p:menuitem id="m_messagerie" value="Messagerie" icon="pi pi-comments" outcome="#{paths.communicationConversations}" />
<p:menuitem id="m_mes_notifications" value="Mes Notifications" icon="pi pi-bell" outcome="/pages/secure/communication/notifications" /> <p:menuitem id="m_mes_notifications" value="Mes Notifications" icon="pi pi-bell" outcome="#{paths.communicationNotifications}" />
</p:submenu> </p:submenu>
<!-- ════════════════════════════════════════════════════════ --> <!-- ════════════════════════════════════════════════════════ -->
<!-- DOCUMENTS --> <!-- DOCUMENTS -->
<!-- ════════════════════════════════════════════════════════ --> <!-- ════════════════════════════════════════════════════════ -->
<p:submenu id="m_documents" label="Documents" icon="pi pi-folder" rendered="#{menuBean.documentsMenuVisible}"> <p:submenu id="m_documents" label="Documents" icon="pi pi-folder" rendered="#{menuBean.documentsMenuVisible}">
<p:menuitem id="m_mes_documents" value="Mes Documents" icon="pi pi-file" outcome="/pages/secure/documents/mes-documents" /> <p:menuitem id="m_mes_documents" value="Mes Documents" icon="pi pi-file" outcome="#{paths.documentsMesDocuments}" />
</p:submenu> </p:submenu>
<!-- ════════════════════════════════════════════════════════ --> <!-- ════════════════════════════════════════════════════════ -->
<!-- RAPPORTS ET ANALYSES --> <!-- RAPPORTS ET ANALYSES -->
<!-- ════════════════════════════════════════════════════════ --> <!-- ════════════════════════════════════════════════════════ -->
<p:submenu id="m_rapports" label="Rapports" icon="pi pi-chart-bar" rendered="#{menuBean.rapportsMenuVisible}"> <p:submenu id="m_rapports" label="Rapports" icon="pi pi-chart-bar" rendered="#{menuBean.rapportsMenuVisible}">
<p:menuitem id="m_tableaux_bord" value="Tableaux de Bord" icon="pi pi-chart-line" outcome="/pages/secure/rapport/tableaux-bord" /> <p:menuitem id="m_tableaux_bord" value="Tableaux de Bord" icon="pi pi-chart-line" outcome="#{paths.rapportTableauxBord}" />
<p:menuitem id="m_rapport_membres" value="Rapport Membres" icon="pi pi-users" outcome="/pages/secure/rapport/membres" /> <p:menuitem id="m_rapport_membres" value="Rapport Membres" icon="pi pi-users" outcome="#{paths.rapportMembres}" />
<p:menuitem id="m_rapport_finances" value="Rapport Financier" icon="pi pi-dollar" outcome="/pages/secure/rapport/finances" rendered="#{menuBean.rapportFinancierVisible}" /> <p:menuitem id="m_rapport_finances" value="Rapport Financier" icon="pi pi-dollar" outcome="#{paths.rapportFinances}" rendered="#{menuBean.rapportFinancierVisible}" />
<p:menuitem id="m_rapport_activites" value="Rapport d'Activités" icon="pi pi-chart-line" outcome="/pages/secure/rapport/activites" /> <p:menuitem id="m_rapport_activites" value="Rapport d'Activités" icon="pi pi-chart-line" outcome="#{paths.rapportActivites}" />
<p:menuitem id="m_export" value="Exports" icon="pi pi-download" outcome="/pages/secure/rapport/export" rendered="#{menuBean.exportsPersonnalisesVisible}" /> <p:menuitem id="m_export" value="Exports" icon="pi pi-download" outcome="#{paths.rapportExport}" rendered="#{menuBean.exportsPersonnalisesVisible}" />
</p:submenu> </p:submenu>
<!-- ════════════════════════════════════════════════════════ --> <!-- ════════════════════════════════════════════════════════ -->
<!-- MON ESPACE PERSONNEL --> <!-- MON ESPACE PERSONNEL -->
<!-- ════════════════════════════════════════════════════════ --> <!-- ════════════════════════════════════════════════════════ -->
<p:submenu id="m_personnel" label="Mon Espace" icon="pi pi-user"> <p:submenu id="m_personnel" label="Mon Espace" icon="pi pi-user">
<p:menuitem id="m_mon_profil" value="Mon Profil" icon="pi pi-user-edit" outcome="/pages/secure/personnel/profil" /> <p:menuitem id="m_mon_profil" value="Mon Profil" icon="pi pi-user-edit" outcome="#{paths.personnelProfil}" />
<p:menuitem id="m_mes_preferences" value="Mes Préférences" icon="pi pi-cog" outcome="/pages/secure/personnel/preferences" /> <p:menuitem id="m_mes_preferences" value="Mes Préférences" icon="pi pi-cog" outcome="#{paths.personnelPreferences}" />
<p:menuitem id="m_personnel_notifications" value="Mes Notifications" icon="pi pi-bell" outcome="/pages/secure/personnel/notifications" /> <p:menuitem id="m_personnel_notifications" value="Mes Notifications" icon="pi pi-bell" outcome="#{paths.personnelNotifications}" />
<p:menuitem id="m_parametres_compte" value="Paramètres Compte" icon="pi pi-lock" outcome="/pages/secure/personnel/parametres" /> <p:menuitem id="m_parametres_compte" value="Paramètres Compte" icon="pi pi-lock" outcome="#{paths.personnelParametres}" />
</p:submenu> </p:submenu>
<!-- ════════════════════════════════════════════════════════ --> <!-- ════════════════════════════════════════════════════════ -->
<!-- AIDE ET SUPPORT --> <!-- AIDE ET SUPPORT -->
<!-- ════════════════════════════════════════════════════════ --> <!-- ════════════════════════════════════════════════════════ -->
<p:submenu id="m_aide_documentation" label="Aide" icon="pi pi-question-circle"> <p:submenu id="m_aide_documentation" label="Aide" icon="pi pi-question-circle">
<p:menuitem id="m_faq" value="Questions Fréquentes" icon="pi pi-question" outcome="/pages/secure/aide/faq" /> <p:menuitem id="m_faq" value="Questions Fréquentes" icon="pi pi-question" outcome="#{paths.aideFaq}" />
<p:menuitem id="m_support" value="Contacter le Support" icon="pi pi-phone" outcome="/pages/secure/aide/support" /> <p:menuitem id="m_support" value="Contacter le Support" icon="pi pi-phone" outcome="#{paths.aideSupport}" />
<p:menuitem id="m_apropos" value="À Propos" icon="pi pi-info" outcome="/pages/secure/aide/apropos" /> <p:menuitem id="m_apropos" value="À Propos" icon="pi pi-info" outcome="#{paths.aideApropos}" />
</p:submenu> </p:submenu>
</fr:menu> </fr:menu>

View File

@@ -21,7 +21,7 @@
<a href="#" class="menu-button"> <a href="#" class="menu-button">
<i class="pi pi-bars"/> <i class="pi pi-bars"/>
</a> </a>
<h:link id="logolink" outcome="/pages/secure/dashboard" styleClass="layout-topbar-logo" style="display:none"/> <h:link id="logolink" outcome="#{paths.dashboard}" styleClass="layout-topbar-logo" style="display:none"/>
</div> </div>
<!-- CENTER - Menu --> <!-- CENTER - Menu -->

View File

@@ -0,0 +1,85 @@
package dev.lions.unionflow.client.constants;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
/**
* Vérifie que chaque constante {@link ViewPaths} pointe vers un fichier xhtml existant
* sous {@code META-INF/resources/}.
*
* <p>Garantie de non-régression : tout outcome utilisé en navigation existe physiquement.
*/
class ViewPathsConsistencyTest {
/** Constantes auxquelles aucun fichier physique n'est attaché (suffixes / racines techniques). */
private static final java.util.Set<String> NON_FILE_CONSTANTS = java.util.Set.of(
"REDIRECT_SUFFIX", "ROOT", "INDEX");
/**
* Pages référencées par le code mais pas encore implémentées (dette pré-Sprint 12).
*
* <p>Action : créer les xhtml correspondants dans un sprint dédié, puis retirer cette liste.
* Le fait de centraliser via {@link ViewPaths} a permis de détecter ces pages fantômes.
*/
private static final java.util.Set<String> KNOWN_MISSING_PAGES = java.util.Set.of(
"EVENEMENT_BILAN_DETAIL",
"ADMIN_PARAMETRES",
"MEMBRE_PARAMETRES");
@Test
@DisplayName("Chaque constante ViewPaths pointe vers un .xhtml existant en classpath")
void chaquePathExisteCommeFichier() throws Exception {
List<String> manquants = new ArrayList<>();
for (Field f : ViewPaths.class.getDeclaredFields()) {
if (!Modifier.isStatic(f.getModifiers())
|| !Modifier.isFinal(f.getModifiers())
|| !f.getType().equals(String.class)) {
continue;
}
String name = f.getName();
if (NON_FILE_CONSTANTS.contains(name)) continue;
if (KNOWN_MISSING_PAGES.contains(name)) continue; // dette pré-Sprint 12
String path = (String) f.get(null);
String resourcePath = "META-INF/resources" + path + ".xhtml";
URL url = Thread.currentThread().getContextClassLoader().getResource(resourcePath);
if (url == null) {
manquants.add(name + "" + resourcePath);
}
}
if (!manquants.isEmpty()) {
fail("Paths sans fichier xhtml correspondant :\n " + String.join("\n ", manquants));
}
}
@Test
@DisplayName("REDIRECT_SUFFIX commence par '?'")
void redirectSuffixFormat() {
assertNotNull(ViewPaths.REDIRECT_SUFFIX);
assertTrue(ViewPaths.REDIRECT_SUFFIX.startsWith("?"));
assertTrue(ViewPaths.REDIRECT_SUFFIX.contains("faces-redirect=true"));
}
@Test
@DisplayName("Aucune constante n'est null ou blanche")
void aucuneConstanteVide() throws Exception {
for (Field f : ViewPaths.class.getDeclaredFields()) {
if (!Modifier.isStatic(f.getModifiers())
|| !f.getType().equals(String.class)) continue;
String value = (String) f.get(null);
assertNotNull(value, "Constante " + f.getName() + " null");
assertTrue(!value.isBlank(), "Constante " + f.getName() + " vide");
}
}
}