package dev.lions.unionflow.client.view; import jakarta.enterprise.context.SessionScoped; import jakarta.inject.Named; import jakarta.annotation.PostConstruct; import java.io.Serializable; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.List; import java.util.UUID; import org.jboss.logging.Logger; import java.util.stream.Collectors; @Named("documentsBean") @SessionScoped public class DocumentsBean implements Serializable { private static final long serialVersionUID = 1L; private static final Logger LOG = Logger.getLogger(DocumentsBean.class); // Constantes de navigation outcomes (WOU/DRY - réutilisables) private static final String OUTCOME_DOCUMENTS_VERSIONS = "documentsVersionsPage"; private List tousLesDocuments; private List documentsFiltres; private List documentsSelectionnes; private List dossiersAffichage; private List dossiersDisponibles; private List cheminNavigation; private Document documentSelectionne; private Dossier dossierSelectionne; private NouveauDocument nouveauDocument; private Filtres filtres; private StatistiquesDocuments statistiques; private String modeAffichage = "GRID"; // GRID ou LIST private UUID dossierActuelId; @PostConstruct public void init() { initializeFiltres(); initializeStatistiques(); initializeDossiers(); initializeDocuments(); initializeNouveauDocument(); initializeNavigation(); appliquerFiltres(); } private void initializeFiltres() { filtres = new Filtres(); documentsSelectionnes = new ArrayList<>(); } private void initializeStatistiques() { statistiques = new StatistiquesDocuments(); try { // Les statistiques seront calculées depuis les documents réels // Pour l'instant, initialiser avec des valeurs par défaut statistiques.setTotalDocuments(tousLesDocuments != null ? tousLesDocuments.size() : 0); statistiques.setTotalDossiers(dossiersDisponibles != null ? dossiersDisponibles.size() : 0); statistiques.setEspaceUtilise("0 GB"); statistiques.setPartagesMois(0); } catch (Exception e) { LOG.errorf(e, "Erreur lors du calcul des statistiques"); statistiques.setTotalDocuments(0); statistiques.setTotalDossiers(0); statistiques.setEspaceUtilise("0 GB"); statistiques.setPartagesMois(0); } } private void initializeDossiers() { dossiersAffichage = new ArrayList<>(); dossiersDisponibles = new ArrayList<>(); // Les dossiers seront chargés depuis l'API backend // Pour l'instant, laisser les listes vides plutôt que des données mockées } private void initializeDocuments() { tousLesDocuments = new ArrayList<>(); // Les documents seront chargés depuis l'API backend // Pour l'instant, laisser la liste vide plutôt que des données mockées } private void initializeNouveauDocument() { nouveauDocument = new NouveauDocument(); nouveauDocument.setAccesRestreint(false); } private void initializeNavigation() { cheminNavigation = new ArrayList<>(); NiveauNavigation racine = new NiveauNavigation(); racine.setNom("📁 Racine"); racine.setDossierId(null); cheminNavigation.add(racine); // Si on est dans un dossier spécifique, ajouter le niveau if (dossierActuelId != null) { Dossier dossierActuel = dossiersDisponibles.stream() .filter(d -> d.getId().equals(dossierActuelId)) .findFirst() .orElse(null); if (dossierActuel != null) { NiveauNavigation niveau = new NiveauNavigation(); niveau.setNom(dossierActuel.getNom()); niveau.setDossierId(dossierActuel.getId()); cheminNavigation.add(niveau); } } } private void appliquerFiltres() { documentsFiltres = tousLesDocuments.stream() .filter(this::appliquerFiltre) .collect(Collectors.toList()); } private boolean appliquerFiltre(Document document) { // Filtre par dossier actuel if (dossierActuelId != null) { if (document.getDossierId() == null || !document.getDossierId().equals(dossierActuelId)) { return false; } } else { // Si on est à la racine, ne montrer que les documents sans dossier parent if (document.getDossierId() != null) { return false; } } if (filtres.getNom() != null && !filtres.getNom().trim().isEmpty()) { if (!document.getNom().toLowerCase().contains(filtres.getNom().toLowerCase())) { return false; } } if (filtres.getType() != null && !filtres.getType().trim().isEmpty()) { if (!document.getType().equals(filtres.getType())) { return false; } } if (filtres.getCategorie() != null && !filtres.getCategorie().trim().isEmpty()) { if (!document.getCategorie().equals(filtres.getCategorie())) { return false; } } if (filtres.getStatut() != null && !filtres.getStatut().trim().isEmpty()) { if (!document.getStatut().equals(filtres.getStatut())) { return false; } } if (filtres.getAuteur() != null && !filtres.getAuteur().trim().isEmpty()) { if (!document.getAuteur().toLowerCase().contains(filtres.getAuteur().toLowerCase())) { return false; } } if (filtres.getMotsCles() != null && !filtres.getMotsCles().trim().isEmpty()) { if (!document.getMotsCles().toLowerCase().contains(filtres.getMotsCles().toLowerCase())) { return false; } } if (filtres.getDateDebut() != null) { if (document.getDateCreation().toLocalDate().isBefore(filtres.getDateDebut())) { return false; } } if (filtres.getDateFin() != null) { if (document.getDateCreation().toLocalDate().isAfter(filtres.getDateFin())) { return false; } } if (filtres.getTailleMax() != null && filtres.getTailleMax() > 0) { long tailleMaxBytes = filtres.getTailleMax().longValue() * 1024 * 1024; // Conversion MB vers bytes if (document.getTailleBytes() > tailleMaxBytes) { return false; } } return true; } // Actions public void rechercher() { appliquerFiltres(); } public void reinitialiserFiltres() { filtres = new Filtres(); appliquerFiltres(); } public void changerModeAffichage(String mode) { this.modeAffichage = mode; } public void naviguerVersDossier(Dossier dossier) { this.dossierActuelId = dossier.getId(); initializeNavigation(); appliquerFiltres(); } public void telechargerNouveauDocument() { Document nouveau = new Document(); nouveau.setId(UUID.randomUUID()); nouveau.setNom("Nouveau Document " + (tousLesDocuments.size() + 1)); nouveau.setCategorie(nouveauDocument.getCategorie()); nouveau.setDescription(nouveauDocument.getDescription()); nouveau.setMotsCles(nouveauDocument.getMotsCles()); nouveau.setDossierId(nouveauDocument.getDossierId()); nouveau.setStatut("BROUILLON"); nouveau.setAuteur("Utilisateur Actuel"); nouveau.setDateCreation(LocalDateTime.now()); nouveau.setDateModification(LocalDateTime.now()); nouveau.setTailleBytes(1024000L); // 1MB par défaut nouveau.setNombreVues(0); nouveau.setNombreTelecharements(0); nouveau.setType("PDF"); // Type par défaut tousLesDocuments.add(nouveau); appliquerFiltres(); LOG.infof("Document téléchargé: %s", nouveau.getNom()); initializeNouveauDocument(); } public void telechargerDocument(Document document) { document.setNombreTelecharements(document.getNombreTelecharements() + 1); LOG.infof("Téléchargement du document: %s", document.getNom()); } public void supprimerDocument(Document document) { tousLesDocuments.remove(document); appliquerFiltres(); LOG.infof("Document supprimé: %s", document.getNom()); } public void dupliquerDocument() { if (documentSelectionne != null) { Document copie = new Document(); copie.setId(UUID.randomUUID()); copie.setNom(documentSelectionne.getNom() + " (Copie)"); copie.setType(documentSelectionne.getType()); copie.setCategorie(documentSelectionne.getCategorie()); copie.setStatut("BROUILLON"); copie.setAuteur("Utilisateur Actuel"); copie.setDescription(documentSelectionne.getDescription()); copie.setMotsCles(documentSelectionne.getMotsCles()); copie.setDossierId(documentSelectionne.getDossierId()); copie.setTailleBytes(documentSelectionne.getTailleBytes()); copie.setDateCreation(LocalDateTime.now()); copie.setDateModification(LocalDateTime.now()); copie.setNombreVues(0); copie.setNombreTelecharements(0); tousLesDocuments.add(copie); appliquerFiltres(); LOG.infof("Document dupliqué: %s", copie.getNom()); } } public void archiverDocument() { if (documentSelectionne != null) { documentSelectionne.setStatut("ARCHIVE"); LOG.infof("Document archivé: %s", documentSelectionne.getNom()); appliquerFiltres(); } } public void supprimerDefinitivement() { if (documentSelectionne != null) { tousLesDocuments.remove(documentSelectionne); appliquerFiltres(); LOG.infof("Document supprimé définitivement: %s", documentSelectionne.getNom()); } } public String voirHistoriqueVersions() { // Utilisation de navigation outcome au lieu de chemin direct (WOU/DRY) return OUTCOME_DOCUMENTS_VERSIONS + "?id=" + documentSelectionne.getId() + "&faces-redirect=true"; } public boolean estSelectionne(Document document) { return documentsSelectionnes.contains(document); } public void toggleSelection(Document document) { if (documentsSelectionnes.contains(document)) { documentsSelectionnes.remove(document); } else { documentsSelectionnes.add(document); } } // Getters et Setters public List getTousLesDocuments() { return tousLesDocuments; } public void setTousLesDocuments(List tousLesDocuments) { this.tousLesDocuments = tousLesDocuments; } public List getDocumentsFiltres() { return documentsFiltres; } public void setDocumentsFiltres(List documentsFiltres) { this.documentsFiltres = documentsFiltres; } public List getDocumentsSelectionnes() { return documentsSelectionnes; } public void setDocumentsSelectionnes(List documentsSelectionnes) { this.documentsSelectionnes = documentsSelectionnes; } public List getDossiersAffichage() { return dossiersAffichage; } public void setDossiersAffichage(List dossiersAffichage) { this.dossiersAffichage = dossiersAffichage; } public List getDossiersDisponibles() { return dossiersDisponibles; } public void setDossiersDisponibles(List dossiersDisponibles) { this.dossiersDisponibles = dossiersDisponibles; } public List getCheminNavigation() { return cheminNavigation; } public void setCheminNavigation(List cheminNavigation) { this.cheminNavigation = cheminNavigation; } public Document getDocumentSelectionne() { return documentSelectionne; } public void setDocumentSelectionne(Document documentSelectionne) { this.documentSelectionne = documentSelectionne; } public Dossier getDossierSelectionne() { return dossierSelectionne; } public void setDossierSelectionne(Dossier dossierSelectionne) { this.dossierSelectionne = dossierSelectionne; } public NouveauDocument getNouveauDocument() { return nouveauDocument; } public void setNouveauDocument(NouveauDocument nouveauDocument) { this.nouveauDocument = nouveauDocument; } public Filtres getFiltres() { return filtres; } public void setFiltres(Filtres filtres) { this.filtres = filtres; } public StatistiquesDocuments getStatistiques() { return statistiques; } public void setStatistiques(StatistiquesDocuments statistiques) { this.statistiques = statistiques; } public String getModeAffichage() { return modeAffichage; } public void setModeAffichage(String modeAffichage) { this.modeAffichage = modeAffichage; } public UUID getDossierActuelId() { return dossierActuelId; } public void setDossierActuelId(UUID dossierActuelId) { this.dossierActuelId = dossierActuelId; } // Classes internes public static class Document { private UUID id; private String nom; private String description; private String type; private String categorie; private String statut; private String auteur; private String motsCles; private UUID dossierId; private long tailleBytes; private LocalDateTime dateCreation; private LocalDateTime dateModification; private int nombreVues; private int nombreTelecharements; private boolean accesRestreint; // Getters et setters public UUID getId() { return id; } public void setId(UUID id) { this.id = id; } public String getNom() { return nom; } public void setNom(String nom) { this.nom = nom; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public String getType() { return type; } public void setType(String type) { this.type = type; } public String getCategorie() { return categorie; } public void setCategorie(String categorie) { this.categorie = categorie; } public String getStatut() { return statut; } public void setStatut(String statut) { this.statut = statut; } public String getAuteur() { return auteur; } public void setAuteur(String auteur) { this.auteur = auteur; } public String getMotsCles() { return motsCles; } public void setMotsCles(String motsCles) { this.motsCles = motsCles; } public UUID getDossierId() { return dossierId; } public void setDossierId(UUID dossierId) { this.dossierId = dossierId; } public long getTailleBytes() { return tailleBytes; } public void setTailleBytes(long tailleBytes) { this.tailleBytes = tailleBytes; } public LocalDateTime getDateCreation() { return dateCreation; } public void setDateCreation(LocalDateTime dateCreation) { this.dateCreation = dateCreation; } public LocalDateTime getDateModification() { return dateModification; } public void setDateModification(LocalDateTime dateModification) { this.dateModification = dateModification; } public int getNombreVues() { return nombreVues; } public void setNombreVues(int nombreVues) { this.nombreVues = nombreVues; } public int getNombreTelecharements() { return nombreTelecharements; } public void setNombreTelecharements(int nombreTelecharements) { this.nombreTelecharements = nombreTelecharements; } public boolean isAccesRestreint() { return accesRestreint; } public void setAccesRestreint(boolean accesRestreint) { this.accesRestreint = accesRestreint; } // Propriétés dérivées public String getTypeIcon() { return switch (type) { case "PDF" -> "pi-file-pdf"; case "WORD" -> "pi-file-word"; case "EXCEL" -> "pi-file-excel"; case "POWERPOINT" -> "pi-file"; case "IMAGE" -> "pi-image"; default -> "pi-file"; }; } public String getTypeCouleur() { return switch (type) { case "PDF" -> "red-500"; case "WORD" -> "blue-500"; case "EXCEL" -> "green-500"; case "POWERPOINT" -> "orange-500"; case "IMAGE" -> "purple-500"; default -> "gray-500"; }; } public String getCategorieLibelle() { return switch (categorie) { case "ADMINISTRATIF" -> "Administratif"; case "FINANCIER" -> "Financier"; case "JURIDIQUE" -> "Juridique"; case "COMMUNICATION" -> "Communication"; case "FORMATION" -> "Formation"; case "AUTRE" -> "Autre"; default -> categorie; }; } public String getCategorieSeverity() { return switch (categorie) { case "ADMINISTRATIF" -> "info"; case "FINANCIER" -> "success"; case "JURIDIQUE" -> "danger"; case "COMMUNICATION" -> "warning"; case "FORMATION" -> "primary"; case "AUTRE" -> "secondary"; default -> "secondary"; }; } public String getStatutLibelle() { return switch (statut) { case "BROUILLON" -> "Brouillon"; case "VALIDE" -> "Validé"; case "ARCHIVE" -> "Archivé"; case "EXPIRE" -> "Expiré"; default -> statut; }; } public String getStatutSeverity() { return switch (statut) { case "BROUILLON" -> "warning"; case "VALIDE" -> "success"; case "ARCHIVE" -> "secondary"; case "EXPIRE" -> "danger"; default -> "secondary"; }; } public String getTaille() { if (tailleBytes < 1024) { return tailleBytes + " B"; } else if (tailleBytes < 1024 * 1024) { return Math.round(tailleBytes / 1024.0) + " KB"; } else { return Math.round(tailleBytes / (1024.0 * 1024)) + " MB"; } } public String getDateCreationFormatee() { if (dateCreation == null) return ""; return dateCreation.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")); } public String getDateCreationRelative() { if (dateCreation == null) return ""; long jours = ChronoUnit.DAYS.between(dateCreation.toLocalDate(), LocalDate.now()); if (jours == 0) return "Aujourd'hui"; if (jours == 1) return "Hier"; if (jours < 7) return "Il y a " + jours + " jours"; if (jours < 30) return "Il y a " + (jours / 7) + " semaine" + (jours / 7 > 1 ? "s" : ""); return "Il y a " + (jours / 30) + " mois"; } } public static class Dossier { private UUID id; private String nom; private String couleur; private int nombreDocuments; private LocalDateTime derniereModification; private String cheminComplet; // Getters et setters public UUID getId() { return id; } public void setId(UUID id) { this.id = id; } public String getNom() { return nom; } public void setNom(String nom) { this.nom = nom; } public String getCouleur() { return couleur; } public void setCouleur(String couleur) { this.couleur = couleur; } public int getNombreDocuments() { return nombreDocuments; } public void setNombreDocuments(int nombreDocuments) { this.nombreDocuments = nombreDocuments; } public LocalDateTime getDerniereModification() { return derniereModification; } public void setDerniereModification(LocalDateTime derniereModification) { this.derniereModification = derniereModification; } public String getCheminComplet() { return cheminComplet; } public void setCheminComplet(String cheminComplet) { this.cheminComplet = cheminComplet; } public String getDerniereModificationRelative() { if (derniereModification == null) return ""; long jours = ChronoUnit.DAYS.between(derniereModification.toLocalDate(), LocalDate.now()); if (jours == 0) return "aujourd'hui"; if (jours == 1) return "hier"; return "il y a " + jours + " jours"; } } public static class NouveauDocument { private String categorie; private String description; private String motsCles; private UUID dossierId; private boolean accesRestreint; // Getters et setters public String getCategorie() { return categorie; } public void setCategorie(String categorie) { this.categorie = categorie; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public String getMotsCles() { return motsCles; } public void setMotsCles(String motsCles) { this.motsCles = motsCles; } public UUID getDossierId() { return dossierId; } public void setDossierId(UUID dossierId) { this.dossierId = dossierId; } public boolean isAccesRestreint() { return accesRestreint; } public void setAccesRestreint(boolean accesRestreint) { this.accesRestreint = accesRestreint; } } public static class Filtres { private String nom; private String type; private String categorie; private String statut; private String auteur; private String motsCles; private LocalDate dateDebut; private LocalDate dateFin; private Double tailleMax; // Getters et setters public String getNom() { return nom; } public void setNom(String nom) { this.nom = nom; } public String getType() { return type; } public void setType(String type) { this.type = type; } public String getCategorie() { return categorie; } public void setCategorie(String categorie) { this.categorie = categorie; } public String getStatut() { return statut; } public void setStatut(String statut) { this.statut = statut; } public String getAuteur() { return auteur; } public void setAuteur(String auteur) { this.auteur = auteur; } public String getMotsCles() { return motsCles; } public void setMotsCles(String motsCles) { this.motsCles = motsCles; } public LocalDate getDateDebut() { return dateDebut; } public void setDateDebut(LocalDate dateDebut) { this.dateDebut = dateDebut; } public LocalDate getDateFin() { return dateFin; } public void setDateFin(LocalDate dateFin) { this.dateFin = dateFin; } public Double getTailleMax() { return tailleMax; } public void setTailleMax(Double tailleMax) { this.tailleMax = tailleMax; } } public static class StatistiquesDocuments { private int totalDocuments; private int totalDossiers; private String espaceUtilise; private int partagesMois; // Getters et setters public int getTotalDocuments() { return totalDocuments; } public void setTotalDocuments(int totalDocuments) { this.totalDocuments = totalDocuments; } public int getTotalDossiers() { return totalDossiers; } public void setTotalDossiers(int totalDossiers) { this.totalDossiers = totalDossiers; } public String getEspaceUtilise() { return espaceUtilise; } public void setEspaceUtilise(String espaceUtilise) { this.espaceUtilise = espaceUtilise; } public int getPartagesMois() { return partagesMois; } public void setPartagesMois(int partagesMois) { this.partagesMois = partagesMois; } } public static class NiveauNavigation { private String nom; private UUID dossierId; // Getters et setters public String getNom() { return nom; } public void setNom(String nom) { this.nom = nom; } public UUID getDossierId() { return dossierId; } public void setDossierId(UUID dossierId) { this.dossierId = dossierId; } } }