diff --git a/dev/deploiment_sur_dataviz.R b/dev/deploiment_sur_dataviz.R
index b41652ec1546e3c71085d59fbf1038129f9b204b..7abc3ee62655cf61dd6e4d60ed49156cfc7267ae 100644
--- a/dev/deploiment_sur_dataviz.R
+++ b/dev/deploiment_sur_dataviz.R
@@ -12,6 +12,6 @@ to_svr_dataviz_ftp <- function(fic = "app/shiny_siclop.RData") {
 
 # fichiers à transférer
 app_files <- c(list.files("R/", full.names = TRUE, recursive = TRUE),
-               "dataviz_gitlabr.Rproj","github.RData","gitlab_forge.RData","gitlab.RData")
+               "dataviz_gitlabr.Rproj","github.RData","gitlab_forge.RData","gitlab.RData","date_MAJ.RData")
 # Exécution des transferts
 lapply(X = app_files, FUN = to_svr_dataviz_ftp)
diff --git a/dev/github_extraire.R b/dev/github_extraire.R
index 3f96c5a382cefba47d42c4cac4b6283e97b41502..e8763ce2f054bb9a872951c6c46f431188c7f809 100644
--- a/dev/github_extraire.R
+++ b/dev/github_extraire.R
@@ -1,16 +1,17 @@
-#dernier -----
 # Charger les packages nécessaires
 library(httr)
 library(jsonlite)
 library(dplyr)
 library(DT)
 # Récupérer le token GitHub depuis l'environnement
-api_key <- Sys.getenv("GITHUB_PAT")
 
+extract_before_at <- function(email) {
+  sub("@.*", "", email)
+}
 # Fonction pour récupérer les commits d'un projet GitHub avec clé API
 get_github_commits <- function(repo) {
   url <- paste0("https://api.github.com/repos/", repo, "/commits")
-  response <- GET(url, authenticate(api_key, ""))  # Utilisation de la clé API
+  response <- GET(url, authenticate(Sys.getenv("GITHUB_PAT"), ""))  # Utilisation de la clé API
   if (status_code(response) != 200) {
     stop("Failed to fetch commits from GitHub API")
   }
@@ -19,15 +20,16 @@ get_github_commits <- function(repo) {
     mutate(project_name = repo,   # Ajouter le nom du projet
            type = "commit",       # Spécifier le type comme "commit"
            message = commit.message,  # Utiliser le message du commit
-           last_updated = commit.committer.date) %>%  # Date de la dernière mise à jour
-    select(project_name, type, message, last_updated)  # Conserver les colonnes pertinentes
+           author = extract_before_at(commit.committer.email) , # Ajout de l'auteur
+           updated_at = commit.committer.date) %>%  # Date de la dernière mise à jour
+    select(project_name, type, message, updated_at,author)  # Conserver les colonnes pertinentes
   return(commits)
 }
 
 # Fonction pour récupérer les issues d'un projet GitHub avec clé API
 get_github_issues <- function(repo) {
   url <- paste0("https://api.github.com/repos/", repo, "/issues?state=all")
-  response <- GET(url, authenticate(api_key, ""))  # Utilisation de la clé API
+  response <- GET(url, authenticate(Sys.getenv("GITHUB_PAT"), ""))  # Utilisation de la clé API
   if (status_code(response) != 200) {
     stop("Failed to fetch issues from GitHub API")
   }
@@ -36,11 +38,23 @@ get_github_issues <- function(repo) {
     mutate(project_name = repo,   # Ajouter le nom du projet
            type = "issue",        # Spécifier le type comme "issue"
            message = title,       # Utiliser le titre de l'issue
-           last_updated = updated_at) %>%  # Date de la dernière mise à jour
-    select(project_name, type, message, last_updated)  # Conserver les colonnes pertinentes
+           author = user.login , # Ajout de l'auteur
+           updated_at = updated_at) %>%  # Date de la dernière mise à jour
+    select(project_name, type, message, updated_at,author)  # Conserver les colonnes pertinentes
   return(issues)
 }
 
+get_github_topics <- function(repo) {
+  url <- paste0("https://api.github.com/repos/", repo, "/topics")
+  response <- GET(url, authenticate(Sys.getenv("GITHUB_PAT"), ""), add_headers(Accept = "application/vnd.github.mercy-preview+json"))
+  if (status_code(response) != 200) {
+    stop("Failed to fetch topics from GitHub API for repo: ", repo)
+  }
+  topics <- fromJSON(content(response, "text"), flatten = TRUE)$names
+  return(data.frame(project_name = repo, topics = paste(topics, collapse = ", "))) # Combine topics en une chaîne unique
+}
+
+
  # Récupérer les commits et les issues pour le projet spyrales/shinygouv
  repo_shinygouv <- "spyrales/shinygouv"
  commits_shinygouv <- get_github_commits(repo_shinygouv)
@@ -64,46 +78,62 @@ get_github_issues <- function(repo) {
  # parcours_r_module_analyse_multi_dimensionnelles
  repo_analyse_multi_dimensionnelles <- "MTES-MCT/parcours_r_module_analyse_multi_dimensionnelles"
  commits_multi_dim <- get_github_commits(repo_analyse_multi_dimensionnelles)
- issues_multi_dim <- get_github_commits(repo_analyse_multi_dimensionnelles)
+ issues_multi_dim <- get_github_issues(repo_analyse_multi_dimensionnelles)
 
  # parcours_r_module_statistiques_descriptives
  repo_stat_desc <- "MTES-MCT/parcours_r_module_statistiques_descriptives"
  commits_stat_desc <- get_github_commits(repo_stat_desc)
- issues_stat_desc <- get_github_commits(repo_stat_desc)
+ issues_stat_desc <- get_github_issues(repo_stat_desc)
 
  # parcours_r_module_publication_rmarkdown
  repo_rmarkdown <- "MTES-MCT/parcours_r_module_publication_rmarkdown"
  commits_rmarkdown <- get_github_commits(repo_rmarkdown)
- issues_rmarkdown <- get_github_commits(repo_rmarkdown)
+ issues_rmarkdown <- get_github_issues(repo_rmarkdown)
  # parcours_r_socle_introduction
  repo_introduction <- "MTES-MCT/parcours_r_socle_introduction"
  commits_introduction <- get_github_commits(repo_introduction)
- issues_introduction <- get_github_commits(repo_introduction)
+ issues_introduction <- get_github_issues(repo_introduction)
 
  # parcours_r_socle_preparation_des_donnees
  repo_preparation_des_donnees <- "MTES-MCT/parcours_r_socle_preparation_des_donnees"
  commits_preparation_des_donnees <- get_github_commits(repo_preparation_des_donnees)
- issues_preparation_des_donnees <- get_github_commits(repo_preparation_des_donnees)
+ issues_preparation_des_donnees <- get_github_issues(repo_preparation_des_donnees)
 
  # savoirfR
  repo_savoirfR <- "MTES-MCT/savoirfR"
  commits_savoirfR <- get_github_commits(repo_savoirfR)
- issues_savoirfR <- get_github_commits(repo_savoirfR)
+ issues_savoirfR <- get_github_issues(repo_savoirfR)
 
  # parcours-r
  repo_parcours_r <- "MTES-MCT/parcours-r"
  commits_parcours_r <- get_github_commits(repo_parcours_r)
- issues_parcours_r <- get_github_commits(repo_parcours_r)
+ issues_parcours_r <- get_github_issues(repo_parcours_r)
 
  # parcours_r_module_datavisualisation
  repo_datavisualisation <- "MTES-MCT/parcours_r_module_datavisualisation"
  commits_datavisualisation <- get_github_commits(repo_datavisualisation)
- issues_datavisualisation <- get_github_commits(repo_datavisualisation)
+ issues_datavisualisation <- get_github_issues(repo_datavisualisation)
 
  # parcours_r_module_analyse_spatiale
  repo_analyse_spatiale <- "MTES-MCT/parcours_r_module_analyse_spatiale"
  commits_analyse_spatiale <- get_github_commits(repo_analyse_spatiale)
- issues_analyse_spatiale <- get_github_commits(repo_analyse_spatiale)
+ issues_analyse_spatiale <- get_github_issues(repo_analyse_spatiale)
+
+ repos <- c(
+   "spyrales/shinygouv", "spyrales/gouvdown",
+   "MTES-MCT/parcours_r_module_applications_shiny",
+   "MTES-MCT/parcours-r_ateliers_rpackage",
+   "MTES-MCT/parcours_r_module_analyse_multi_dimensionnelles",
+   "MTES-MCT/parcours_r_module_statistiques_descriptives",
+   "MTES-MCT/parcours_r_module_publication_rmarkdown",
+   "MTES-MCT/parcours_r_socle_introduction",
+   "MTES-MCT/parcours_r_socle_preparation_des_donnees",
+   "MTES-MCT/savoirfR", "MTES-MCT/parcours-r",
+   "MTES-MCT/parcours_r_module_datavisualisation",
+   "MTES-MCT/parcours_r_module_analyse_spatiale"
+ )
+
+ topics_list <- do.call(rbind, lapply(repos, get_github_topics))
 
  # Combiner les dataframes de commits et issues pour les deux dépôts
  combined_data <- bind_rows(commits_shinygouv, issues_shinygouv,
@@ -120,8 +150,13 @@ get_github_issues <- function(repo) {
                             commits_datavisualisation, issues_datavisualisation,
                             commits_analyse_spatiale, issues_analyse_spatiale
                             )
-combined_data <- rename(combined_data, "updated_at" = 'last_updated')
+ combined_data <- combined_data %>%
+   left_join(topics_list, by = "project_name") %>%
+   mutate(origine = "Github") %>%
+   unique()
+
 # Afficher les premières lignes du tableau combiné
 date_datamart <-format.Date(Sys.Date(), '%d/%m/%Y')
 #save.image("github.RData")
 save(combined_data, file = "github.RData")
+save(date_datamart, file = "date_MAJ.RData")
diff --git a/dev/gitlab_classique.R b/dev/gitlab_classique.R
index 0dd21fce1a995949a2ec9105616bf62256e301aa..bfb98f42cea725322ebdadaec9ef0b17d855d3f5 100644
--- a/dev/gitlab_classique.R
+++ b/dev/gitlab_classique.R
@@ -1,145 +1,152 @@
-# Charger les packages nécessaires
 library(httr)
 library(jsonlite)
 library(dplyr)
 library(DT)
 library(stringr)
+library(gitlabr)
 
-# Variables pour l'API GitLab -----
+set_gitlab_connection(
+  gitlab_url = "https://gitlab.com" ,
+  private_token = Sys.getenv("GITLAB_PAT")
+)
+project_ids <- c(41600697, 19859695, 49118792, 21138017, 44145525, 18441361, 17610613,18439010)
+
+get_project_name <- function(base_url, project_id, private_token) {
+  api_url <- paste0(base_url, "/api/v4/projects/", project_id)
+  response <- GET(api_url, add_headers("PRIVATE-TOKEN" = private_token))
+
+  if (status_code(response) == 200) {
+    project_info <- content(response, as = "parsed", type = "application/json")
+    return(data.frame(id = project_id, name = project_info$name))
+  } else {
+    warning("Impossible de récupérer le projet ID: ", project_id, " - Code: ", status_code(response))
+    return(data.frame(id = project_id, name = NA))
+  }
+}
+
+# Boucle pour récupérer tous les noms de projets
+name_gitlab <- bind_rows(lapply(project_ids, get_project_name,
+                                base_url = "https://gitlab.com",
+                                private_token = Sys.getenv("GITLAB_PAT")))
+name_gitlab$id <- as.character(name_gitlab$id)
+
+# Variables pour l'API GitLab
 base_url <- "https://gitlab.com"
 private_token <- Sys.getenv("GITLAB_PAT")  # Récupération du token depuis Renviron
 
-# Fonction pour gérer la pagination de l'API GitLab avec retry et timeout
-get_all_pages <- function(url, private_token, max_retries = 3) {
-  # Fonction interne pour récupérer une page avec retry
-  get_page <- function(page) {
+
+# Fonction pour gérer la pagination de l'API GitLab avec une limite stricte à 160 pages, en vérifiant la présence de pages suivantes
+# Fonction pour gérer la pagination de l'API GitLab avec une limite stricte à 160 pages
+get_all_pages <- function(url, private_token, max_retries = 3, max_pages = 159) {
+  all_data <- list()
+  page <- 1
+
+  repeat {
+    # Vérification de la condition de fin dans la boucle while
+    if (page > max_pages) {
+      message("Limite de pages atteinte (", max_pages, "). Arrêt de la récupération.")
+      break
+    }
+
     retries <- 0
     success <- FALSE
-    while (!success && retries < max_retries) {
+    message("Traitement de l'URL : ", url, " - Page: ", page)  # Afficher l'URL et la page actuelle
+
+    while (!success && retries < max_retries && page <= max_pages) {
       tryCatch({
-        # Faire la requête GET pour une page spécifique
         response <- GET(
           url,
-          query = list(page = page, per_page = 100),
+          query = list(page = page, per_page = 20),
           add_headers("PRIVATE-TOKEN" = private_token),
-          timeout(120)  # Timeout augmenté à 120 secondes
+          timeout(120)
         )
 
-        # Vérification du statut de la réponse
+        # Sortie en cas d'erreur HTTP autre que 200
         if (status_code(response) != 200) {
           stop("La requête API a échoué avec le statut: ", status_code(response))
         }
 
-        # Extraire les données de la réponse avec l'encodage UTF-8 pour éviter le message
-        data <- fromJSON(content(response, "text", encoding = "UTF-8"), flatten = TRUE)
-        success <- TRUE  # Si la requête réussit, sortir de la boucle
-        return(data)
+        # Récupération des données JSON
+        page_data <- fromJSON(content(response, "text", encoding = "UTF-8"), flatten = TRUE)
 
+        # Si aucune donnée n'est renvoyée, arrêt de la récupération pour ce projet
+        if (length(page_data) == 0) {
+          message("Aucune donnée sur la page ", page, ". Fin de la récupération pour ce projet.")
+          break
+        }
+
+        # Ajouter les données de la page à all_data
+        all_data <- append(all_data, list(page_data))
+        success <- TRUE  # Succès de la récupération
       }, error = function(e) {
         retries <- retries + 1
         message("Erreur de connexion, tentative: ", retries, ". Détails: ", e$message)
-        Sys.sleep(2 * retries)  # Attendre avant de réessayer
+        Sys.sleep(2 * retries)
       })
     }
 
-    if (!success) {
-      stop("Echec de récupération des données après ", max_retries, " tentatives.")
+    # Vérification de la présence d'une page suivante dans l'en-tête "Link"
+    link_header <- headers(response)[["link"]]
+    if (is.null(link_header) || !grepl("rel=\"next\"", link_header)) {
+      message("Pas de page suivante. Fin de la récupération pour ce projet.")
+      break
     }
-  }
 
-  # Initialiser la récupération des données avec la première page
-  first_page_data <- get_page(1)
+    # Passer à la page suivante
+    page <- page + 1
+  }
 
-  # Vérifier s'il y a plusieurs pages en analysant l'en-tête "Link"
-  link_header <- headers(response)[["link"]]
-  if (!is.null(link_header) && str_detect(link_header, "rel=\"next\"")) {
-    # Trouver le nombre total de pages dans l'en-tête
-    num_pages <- max(str_extract_all(link_header, "page=\\d+")[[1]] %>% str_remove_all("page=") %>% as.integer())
+  # Combiner toutes les pages récupérées en un seul dataframe
+  return(bind_rows(all_data))
+}
 
-    # Utiliser lapply pour récupérer les pages suivantes
-    other_pages_data <- lapply(2:num_pages, get_page)
 
-    # Combiner toutes les pages de données
-    all_data <- bind_rows(first_page_data, bind_rows(other_pages_data))
-  } else {
-    # Si une seule page, renvoyer seulement les données de la première page
-    all_data <- first_page_data
-  }
 
-  return(all_data)
-}
 
 # Fonction pour extraire le nom du projet à partir de l'URL
 extract_project_name <- function(web_url) {
-  # Utiliser une expression régulière pour capturer le dernier segment significatif avant "/-/"
   str_extract(web_url, "(?<=/)[^/]+(?=/-/)")
 }
 
-# Fonction pour récupérer les commits d'un projet GitLab
-get_gitlab_commits <- function(base_url, project_id, private_token) {
-  api_url <- paste0(base_url, "/api/v4/projects/", project_id, "/repository/commits")
-
-  # Récupérer toutes les pages avec pagination
-  data <- get_all_pages(api_url, private_token)
-
-  # Harmoniser les types de colonnes et sélectionner les colonnes pertinentes
-  data <- data %>%
-    mutate(
-      id = as.character(id),
-      project_name = extract_project_name(web_url),
-      data_type = "commit",
-      discussion = message,
-      updated_at = committed_date
-    )
-  return(data %>% select(project_name, data_type, discussion, updated_at))
-}
-
 # Fonction pour récupérer les issues d'un projet GitLab
 get_gitlab_issues <- function(base_url, project_id, private_token) {
   api_url <- paste0(base_url, "/api/v4/projects/", project_id, "/issues")
-
-  # Récupérer toutes les pages avec pagination
   data <- get_all_pages(api_url, private_token)
-
-  # Harmoniser les types de colonnes et sélectionner les colonnes pertinentes
   data <- data %>%
     mutate(
-      id = as.character(id),
       project_name = extract_project_name(web_url),
-      data_type = "issue",
-      discussion = title
+      type = "issue",
+      message = title,
+      author = author.username
     )
-  return(data %>% select(project_name, data_type, discussion, updated_at))
+  return(data %>% select(project_name, type, message, updated_at, author))
 }
 
 # Fonction pour récupérer et filtrer les events d'un projet GitLab
 get_gitlab_events <- function(base_url, project_id, private_token) {
   api_url <- paste0(base_url, "/api/v4/projects/", project_id, "/events")
-
-  # Récupérer toutes les pages avec pagination
   data <- get_all_pages(api_url, private_token)
-
-  # Garder seulement les événements où action_name est "commented on"
   data <- data %>%
-    filter(action_name == "commented on") %>%
     mutate(
-      id = as.character(id),
-      project_name = extract_project_name(web_url),
-      data_type = "event",
-      discussion = note.body,
-      updated_at = note.updated_at
-    )
-  return(data %>% select(project_name, data_type, discussion, updated_at))
+      project_name = as.character(project_id),
+      type = if_else((is.null(target_type) | target_type == "") | as.character(target_type) == "Issue" | as.character(action_name) == "joined", # remplecer par  |  as.ch(target-type)=="Issue"
+                     as.character(action_name),
+                     as.character(target_type)),
+      message = note.body,
+      updated_at = created_at,
+      author = author.username
+    ) %>%
+    left_join(name_gitlab, by = c("project_name" = "id")) %>%
+    mutate(project_name = name) %>%
+    select(-name)
+  return(data %>% select(project_name, type, message, updated_at, author))
 }
 
 # Fonction pour récupérer les données d'un projet
 get_data_for_project <- function(base_url, project_id, private_token) {
-  commits_data <- tryCatch(get_gitlab_commits(base_url, project_id, private_token), error = function(e) NULL)
   issues_data <- tryCatch(get_gitlab_issues(base_url, project_id, private_token), error = function(e) NULL)
   events_data <- tryCatch(get_gitlab_events(base_url, project_id, private_token), error = function(e) NULL)
-
-  # Combiner les résultats en un seul dataframe
-  return(bind_rows(commits_data, issues_data, events_data))
+  return(bind_rows(issues_data, events_data))
 }
 
 # Fonction pour traiter plusieurs projets avec lapply
@@ -147,34 +154,81 @@ get_data_from_multiple_projects <- function(base_url, project_ids, private_token
   all_data <- lapply(project_ids, function(project_id) {
     get_data_for_project(base_url, project_id, private_token)
   })
-
-  # Combiner tous les dataframes en un seul
   return(bind_rows(all_data))
 }
 
-# Define the query parameters pour récupérer les projets
-params <- list(
-  include_subgroups = "true",
-  per_page = 100
-)
+# Topics
+get_project_topics <- function(base_url, project_id, private_token) {
+  api_url <- paste0(base_url, "/api/v4/projects/", project_id)
+  response <- GET(api_url, add_headers("PRIVATE-TOKEN" = private_token))
+
+  if (status_code(response) == 200) {
+    project_info <- fromJSON(content(response, "text", encoding = "UTF-8"), flatten = TRUE)
+    return(data.frame(
+      id = as.character(project_info$name),
+      topics = paste(project_info$topics, collapse = ", "),  # Combine les topics en une chaîne de caractères
+      stringsAsFactors = FALSE
+    ))
+  } else {
+    warning("Impossible de récupérer les topics pour le projet ID: ", project_id, " - Code: ", status_code(response))
+    return(data.frame(
+      id = project_id,
+      topics = NA,
+      stringsAsFactors = FALSE
+    ))
+  }
+}
+extract_before_at <- function(email) {
+  sub("@.*", "", email)
+}
+############################################################### -----
+# Fonction générique
+process_projects <- function(project_ids) {
+  result_list <- lapply(project_ids, function(project_id) {
+    # Récupérer les branches du projet
+    branch <- gl_list_branches(project_id)$name
+
+    # Récupérer les commits pour chaque branche
+    branch_results <- lapply(branch, function(b) {
+      data <- gl_get_commits(project_id, ref_name = b, max_page = NA)
+      data <- data %>% mutate(branche = b, project_id = project_id)
+      return(data)
+    })
+
+    # Combiner les résultats pour un seul projet
+    bind_rows(branch_results)
+  })
 
-# Fetch the projects avec pagination et retry
-response <- GET(
-  "https://gitlab-forge.din.developpement-durable.gouv.fr/api/v4/groups/1013/projects",
-  add_headers(`PRIVATE-TOKEN` = Sys.getenv("GITLAB_COM_TOKEN")),
-  query = params,
-  timeout(120)  # Timeout augmenté pour les projets
-)
+  # Combiner tous les projets en un seul dataframe
+  final_result <- bind_rows(result_list)
+
+  # Ajouter une colonne pour indiquer les doublons (en excluant "branche" et "project_id")
+  final_result <- final_result %>%
+    mutate(is_duplicate = duplicated(select(., -c(branche, project_id))))
+
+  return(final_result)
+}
 
-# Parse the JSON content
-projects <- content(response, as = "text", encoding = "UTF-8") %>% fromJSON()
+final_result <- process_projects(project_ids)
+final_result$project_id <- as.character(final_result$project_id)
+final_result <- final_result %>% left_join(name_gitlab, by = c("project_id" = "id")) %>%
+  mutate(project_name = name, type = "commit") %>%
+  select(-name)
+final_result <- final_result %>% mutate(author = extract_before_at(committer_email))
+final_result <- final_result %>% rename( "updated_at" = 'committed_date' )
+fg <- final_result %>% filter(is_duplicate == FALSE) %>% select(project_name,type , message ,updated_at,author)
+###############################################################
 
-# Extract the project IDs
-project_ids <- c(41600697, 19859695, 49118792, 21138017, 18439010, 44145525, 18441361, 17610613)
+# Récupérer les topics pour tous les projets
+projects_topics <- bind_rows(lapply(project_ids, get_project_topics, base_url = base_url, private_token = private_token))
 
 # Récupérer les données pour tous les projets
 all_data_gitlab <- get_data_from_multiple_projects(base_url, project_ids, private_token)
-all_data_gitlab <- rename(all_data_gitlab, "type" = 'data_type',"message" = 'discussion')
-# Afficher un aperçu des données combinées
+all_data_gitlab <- all_data_gitlab %>%
+  filter(!(is.na(all_data_gitlab$type) | is.na(all_data_gitlab$message)) | all_data_gitlab$type == "joined" | all_data_gitlab$type == "WikiPage::Meta")
+all_data_gitlab <- bind_rows(fg,all_data_gitlab)
+all_data_gitlab <- all_data_gitlab %>%
+  mutate(origine ="Gitlab")
+all_data_gitlab <- left_join(all_data_gitlab, projects_topics, by = c("project_name" = "id"))
 # save.image("gitlab.RData")
 save(all_data_gitlab, file = "gitlab.RData")
diff --git a/dev/gitlab_forge.R b/dev/gitlab_forge.R
index d1688d3b1655fd2d80e62cbbfac825917a8209ae..c9baf8cb78189515bc9bde5d605e3ad448d2997a 100644
--- a/dev/gitlab_forge.R
+++ b/dev/gitlab_forge.R
@@ -1,200 +1,193 @@
-# Charger les packages nécessaires
 library(httr)
 library(jsonlite)
 library(dplyr)
 library(DT)
 library(stringr)
+library(gitlabr)
 
-# Variables pour l'API GitLab -----
-base_url <- "https://gitlab-forge.din.developpement-durable.gouv.fr"
-private_token <- Sys.getenv("GITLAB_COM_TOKEN")  # Récupération du token depuis Renviron
+set_gitlab_connection(
+  gitlab_url = "https://gitlab-forge.din.developpement-durable.gouv.fr" ,
+  private_token = Sys.getenv("GITLAB_COM_TOKEN")
+)
 
-# Faire la requête à l'API avec le token d'accès------
-get_all_projects <- function(base_url, gitlab_token) {
-  page <- 1
-  all_projects <- data.frame()
+response <- data.frame()
+# on charge les projets du groupe CSD
+buildres <- function(i){
+  res_proj100 <- GET(
+    "https://gitlab-forge.din.developpement-durable.gouv.fr/api/v4/groups/1013/projects",
+    add_headers(`PRIVATE-TOKEN` = Sys.getenv("GITLAB_COM_TOKEN")),
+    query = list(
+      include_subgroups = "true",
+      per_page = 100,
+      page = i
+    ),
+    timeout(120)  # Timeout augmenté pour les projets
+  )
+  res <- content(res_proj100, as = "text", encoding = "UTF-8") %>% fromJSON()
+  return(res)
+}
+#on réalise une boucle si plus de 100 projets
+x <- 1
+repeat {
+  res <- buildres(x)
+  if (length(res) == 0) {
+    break
+  }
+  response <- bind_rows(response, res)
+  x <- x + 1
+}
+# response <- GET(
+#   "https://gitlab-forge.din.developpement-durable.gouv.fr/api/v4/groups/1013/projects",
+#   add_headers(`PRIVATE-TOKEN` = Sys.getenv("GITLAB_COM_TOKEN")),
+#   query = list(
+#     include_subgroups = "true",
+#     per_page = 1000
+#   ),
+#   timeout(120)  # Timeout augmenté pour les projets
+# )
 
-  repeat {
-    # Faire la requête avec paramètres pour inclure les sous-groupes et gérer la pagination
-    response <- GET(
-      "https://gitlab-forge.din.developpement-durable.gouv.fr/api/v4/groups/1013/projects" ,
-      query = list(include_subgroups = "true", per_page = 100, page = page),
-      add_headers(Authorization = paste("Bearer", private_token))
-    )
+# Parse the JSON content
+projects <- response
 
-    # Vérifier si la requête a réussi
-    if (status_code(response) != 200) {
-      print(paste("Erreur : ", status_code(response)))
-      break
-    }
+# Extract the project IDs
+project_ids <- projects$id
 
-    # Convertir la réponse JSON en une structure R
-    projects <- fromJSON(content(response, as = "text", encoding = "UTF-8"))
+get_project_name <- function(base_url, project_id, private_token) {
+  api_url <- paste0(base_url, "/api/v4/projects/", project_id)
+  response <- GET(api_url, add_headers("PRIVATE-TOKEN" = private_token))
 
-    # Si la réponse est vide ou n'est pas une liste de projets, sortir de la boucle
-    if (length(projects) == 0 || !is.data.frame(projects)) {
-      break
-    }
+  if (status_code(response) == 200) {
+    project_info <- content(response, as = "parsed", type = "application/json")
+    return(data.frame(id = project_id, name = project_info$name))
+  } else {
+    warning("Impossible de récupérer le projet ID: ", project_id, " - Code: ", status_code(response))
+    return(data.frame(id = project_id, name = NA))
+  }
+}
 
-    # Extraire les IDs et les noms des projets
-    project_data <- data.frame(
-      id = projects$id,
-      name = projects$name
-    )
+# Boucle pour récupérer tous les noms de projets
+name_gitlab <- bind_rows(lapply(project_ids, get_project_name,
+                                base_url = "https://gitlab-forge.din.developpement-durable.gouv.fr",
+                                private_token = Sys.getenv("GITLAB_COM_TOKEN")))
+name_gitlab$id <- as.character(name_gitlab$id)
 
-    # Ajouter les projets à la liste complète
-    all_projects <- rbind(all_projects, project_data)
+# Variables pour l'API GitLab
+base_url <- "https://gitlab-forge.din.developpement-durable.gouv.fr"
+private_token <- Sys.getenv("GITLAB_COM_TOKEN")  # Récupération du token depuis Renviron
 
-    # Vérifier si on est à la dernière page en regardant les en-têtes
-    if (is.null(headers(response)$`x-next-page`) || headers(response)$`x-next-page` == "") {
-      break
-    }
 
-    # Passer à la page suivante
-    page <- as.numeric(headers(response)$`x-next-page`)
-  }
+# Fonction pour gérer la pagination de l'API GitLab avec une limite stricte à 160 pages, en vérifiant la présence de pages suivantes
+# Fonction pour gérer la pagination de l'API GitLab avec une limite stricte à 160 pages
+get_all_pages <- function(url, private_token, max_retries = 3, max_pages = 159) {
+  all_data <- list()
+  page <- 1
 
-  return(all_projects)
-}
+  repeat {
+    # Vérification de la condition de fin dans la boucle while
+    if (page > max_pages) {
+      message("Limite de pages atteinte (", max_pages, "). Arrêt de la récupération.")
+      break
+    }
 
-# Récupérer tous les projets
-project_data <- get_all_projects("https://gitlab-forge.din.developpement-durable.gouv.fr/api/v4/groups/1013/projects", private_token)
-project_data$id <- as.character(project_data$id)
-# Fonction pour gérer la pagination de l'API GitLab avec retry et timeout------
-get_all_pages <- function(url, private_token, max_retries = 3) {
-  # Fonction interne pour récupérer une page avec retry
-  get_page <- function(page) {
     retries <- 0
     success <- FALSE
-    while (!success && retries < max_retries) {
+    message("Traitement de l'URL : ", url, " - Page: ", page)  # Afficher l'URL et la page actuelle
+
+    while (!success && retries < max_retries && page <= max_pages) {
       tryCatch({
-        # Faire la requête GET pour une page spécifique
         response <- GET(
           url,
-          query = list(page = page, per_page = 100),
+          query = list(page = page, per_page = 20),
           add_headers("PRIVATE-TOKEN" = private_token),
-          timeout(120)  # Timeout augmenté à 120 secondes
+          timeout(120)
         )
 
-        # Vérification du statut de la réponse
+        # Sortie en cas d'erreur HTTP autre que 200
         if (status_code(response) != 200) {
           stop("La requête API a échoué avec le statut: ", status_code(response))
         }
 
-        # Extraire les données de la réponse avec l'encodage UTF-8 pour éviter le message
-        data <- fromJSON(content(response, "text", encoding = "UTF-8"), flatten = TRUE)
-        success <- TRUE  # Si la requête réussit, sortir de la boucle
-        return(data)
+        # Récupération des données JSON
+        page_data <- fromJSON(content(response, "text", encoding = "UTF-8"), flatten = TRUE)
+
+        # Si aucune donnée n'est renvoyée, arrêt de la récupération pour ce projet
+        if (length(page_data) == 0) {
+          message("Aucune donnée sur la page ", page, ". Fin de la récupération pour ce projet.")
+          break
+        }
 
+        # Ajouter les données de la page à all_data
+        all_data <- append(all_data, list(page_data))
+        success <- TRUE  # Succès de la récupération
       }, error = function(e) {
         retries <- retries + 1
         message("Erreur de connexion, tentative: ", retries, ". Détails: ", e$message)
-        Sys.sleep(2 * retries)  # Attendre avant de réessayer
+        Sys.sleep(2 * retries)
       })
     }
 
-    if (!success) {
-      stop("Echec de récupération des données après ", max_retries, " tentatives.")
+    # Vérification de la présence d'une page suivante dans l'en-tête "Link"
+    link_header <- headers(response)[["link"]]
+    if (is.null(link_header) || !grepl("rel=\"next\"", link_header)) {
+      message("Pas de page suivante. Fin de la récupération pour ce projet.")
+      break
     }
-  }
 
-  # Initialiser la récupération des données avec la première page
-  first_page_data <- get_page(1)
+    # Passer à la page suivante
+    page <- page + 1
+  }
 
-  # Vérifier s'il y a plusieurs pages en analysant l'en-tête "Link"
-  link_header <- headers(response)[["link"]]
-  if (!is.null(link_header) && str_detect(link_header, "rel=\"next\"")) {
-    # Trouver le nombre total de pages dans l'en-tête
-    num_pages <- max(str_extract_all(link_header, "page=\\d+")[[1]] %>% str_remove_all("page=") %>% as.integer())
+  # Combiner toutes les pages récupérées en un seul dataframe
+  return(bind_rows(all_data))
+}
 
-    # Utiliser lapply pour récupérer les pages suivantes
-    other_pages_data <- lapply(2:num_pages, get_page)
 
-    # Combiner toutes les pages de données
-    all_data <- bind_rows(first_page_data, bind_rows(other_pages_data))
-  } else {
-    # Si une seule page, renvoyer seulement les données de la première page
-    all_data <- first_page_data
-  }
 
-  return(all_data)
-}
 
 # Fonction pour extraire le nom du projet à partir de l'URL
 extract_project_name <- function(web_url) {
-  # Utiliser une expression régulière pour capturer le dernier segment significatif avant "/-/"
   str_extract(web_url, "(?<=/)[^/]+(?=/-/)")
 }
 
-# Fonction pour récupérer les commits d'un projet GitLab
-get_gitlab_commits <- function(base_url, project_id, private_token) {
-  api_url <- paste0(base_url, "/api/v4/projects/", project_id, "/repository/commits")
-  # Récupérer toutes les pages avec pagination
-  data <- get_all_pages(api_url, private_token)
-
-  # Harmoniser les types de colonnes et sélectionner les colonnes pertinentes
-  data <- data %>%
-    mutate(
-      id = as.character(id),
-      project_name = as.character(project_id),
-      data_type = "commit",
-      discussion = message,
-      updated_at = committed_date
-    )
-  return(data %>% select(project_name, data_type, discussion, updated_at))
-}
-
 # Fonction pour récupérer les issues d'un projet GitLab
 get_gitlab_issues <- function(base_url, project_id, private_token) {
   api_url <- paste0(base_url, "/api/v4/projects/", project_id, "/issues")
-
-  # Récupérer toutes les pages avec pagination
   data <- get_all_pages(api_url, private_token)
-
-  # Harmoniser les types de colonnes et sélectionner les colonnes pertinentes
   data <- data %>%
     mutate(
-      id = as.character(id),
-      project_name = as.character(project_id),
-      data_type = "issue",
-      discussion = title
+      project_name = extract_project_name(web_url),
+      type = "issue",
+      message = title,
+      author = author.username
     )
-  return(data %>% select(project_name, data_type, discussion, updated_at))
+  return(data %>% select(project_name, type, message, updated_at, author))
 }
 
 # Fonction pour récupérer et filtrer les events d'un projet GitLab
 get_gitlab_events <- function(base_url, project_id, private_token) {
   api_url <- paste0(base_url, "/api/v4/projects/", project_id, "/events")
-
-  # Récupérer toutes les pages avec pagination
   data <- get_all_pages(api_url, private_token)
-
-  # Garder seulement les événements où action_name est "commented on"
-
   data <- data %>%
     mutate(
-      id = as.character(id),
       project_name = as.character(project_id),
-      data_type = if_else((is.na(target_type) | target_type == "") & as.character(action_name) == "joined",
-                          as.character(action_name),
-                          as.character(target_type)),
-      discussion = as.character(target_title),
-      updated_at = created_at
+      type = if_else((is.null(target_type) | target_type == "") | as.character(target_type) == "Issue" | as.character(action_name) == "joined", # remplecer par  |  as.ch(target-type)=="Issue"
+                     as.character(action_name),
+                     as.character(target_type)),
+      message = ifelse(as.character(target_type) == "WikiPage::Meta",target_title,note.body),
+      updated_at = created_at,
+      author = author.username
     ) %>%
-    filter(data_type != "" & !is.na(data_type))
-
-
-  return(data %>% select(project_name, data_type, discussion, updated_at))
+    left_join(name_gitlab, by = c("project_name" = "id")) %>%
+    mutate(project_name = name) %>%
+    select(-name)
+  return(data %>% select(project_name, type, message, updated_at, author))
 }
 
 # Fonction pour récupérer les données d'un projet
 get_data_for_project <- function(base_url, project_id, private_token) {
-  commits_data <- tryCatch(get_gitlab_commits(base_url, project_id, private_token), error = function(e) NULL)
   issues_data <- tryCatch(get_gitlab_issues(base_url, project_id, private_token), error = function(e) NULL)
   events_data <- tryCatch(get_gitlab_events(base_url, project_id, private_token), error = function(e) NULL)
-
-  # Combiner les résultats en un seul dataframe
-  return(bind_rows(commits_data, issues_data, events_data))
+  return(bind_rows(issues_data, events_data))
 }
 
 # Fonction pour traiter plusieurs projets avec lapply
@@ -202,39 +195,79 @@ get_data_from_multiple_projects <- function(base_url, project_ids, private_token
   all_data <- lapply(project_ids, function(project_id) {
     get_data_for_project(base_url, project_id, private_token)
   })
-
-  # Combiner tous les dataframes en un seul
   return(bind_rows(all_data))
 }
 
-# Define the query parameters pour récupérer les projets
-params <- list(
-  include_subgroups = "true",
-  per_page = 100
-)
+get_project_topics <- function(base_url, project_id, private_token) {
+  api_url <- paste0(base_url, "/api/v4/projects/", project_id)
+  response <- GET(api_url, add_headers("PRIVATE-TOKEN" = private_token))
+
+  if (status_code(response) == 200) {
+    project_info <- fromJSON(content(response, "text", encoding = "UTF-8"), flatten = TRUE)
+    return(data.frame(
+      id = as.character(project_info$name),
+      topics = paste(project_info$topics, collapse = ", "),  # Combine les topics en une chaîne de caractères
+      stringsAsFactors = FALSE
+    ))
+  } else {
+    warning("Impossible de récupérer les topics pour le projet ID: ", project_id, " - Code: ", status_code(response))
+    return(data.frame(
+      id = project_id,
+      topics = NA,
+      stringsAsFactors = FALSE
+    ))
+  }
+}
+extract_before_at <- function(email) {
+  sub("@.*", "", email)
+}
+###########################################################
+process_projects <- function(project_ids) {
+  result_list <- lapply(project_ids, function(project_id) {
+    # Récupérer les branches du projet
+    branch <- gl_list_branches(project_id)$name
+
+    # Récupérer les commits pour chaque branche
+    branch_results <- lapply(branch, function(b) {
+      data <- gl_get_commits(project_id, ref_name = b, max_page = NA)
+      Sys.sleep(1)
+      data <- data %>% mutate(branche = b, project_id = project_id)
+      return(data)
+    })
+
+    # Combiner les résultats pour un seul projet
+    bind_rows(branch_results)
+  })
 
-# Fetch the projects avec pagination et retry
-response <- GET(
-  "https://gitlab-forge.din.developpement-durable.gouv.fr/api/v4/groups/1013/projects",
-  add_headers(`PRIVATE-TOKEN` = Sys.getenv("GITLAB_COM_TOKEN")),
-  query = params,
-  timeout(120)  # Timeout augmenté pour les projets
-)
+  # Combiner tous les projets en un seul dataframe
+  final_result <- bind_rows(result_list)
 
-# Parse the JSON content
-projects <- content(response, as = "text", encoding = "UTF-8") %>% fromJSON()
+  # Ajouter une colonne pour indiquer les doublons (en excluant "branche" et "project_id")
+  final_result <- final_result %>%
+    mutate(is_duplicate = duplicated(select(., -c(branche, project_id))))
 
-# Extract the project IDs
-project_ids <- projects$id
+  return(final_result)
+}
+
+final_result <- process_projects(project_ids)
+final_result$project_id <- as.character(final_result$project_id)
+final_result <- final_result %>% left_join(name_gitlab, by = c("project_id" = "id")) %>%
+  mutate(project_name = name, type = "commit") %>%
+  select(-name)
+final_result <- final_result %>% mutate(author = extract_before_at(committer_email))
+final_result <- final_result %>% rename( "updated_at" = 'committed_date'  )
+ff <- final_result %>% filter(is_duplicate == FALSE) %>% select(project_name,type , message ,updated_at,author)
+###########################################################
+
+# Récupérer les topics pour tous les projets
+projects_topics <- bind_rows(lapply(project_ids, get_project_topics, base_url = base_url, private_token = private_token))
 
 # Récupérer les données pour tous les projets
 all_data_forge <- get_data_from_multiple_projects(base_url, project_ids, private_token)
-all_data_forge <- rename(all_data_forge, "type" = 'data_type',"message" = 'discussion')
 all_data_forge <- all_data_forge %>%
-  left_join(project_data, by = c("project_name" = "id")) %>%
-  mutate(project_name = name) %>% select(-name) %>%
-  dplyr::distinct()
-# Afficher un aperçu des données combinées
-# save.image("gitlab_forge.RData")
+  filter(!(is.na(all_data_forge$type) | is.na(all_data_forge$message)) | all_data_forge$type == "joined"|all_data_forge$type == "WikiPage::Meta")
+all_data_forge <- bind_rows(ff,all_data_forge)
+all_data_forge <- all_data_forge %>%
+  mutate(origine ="Gitlab_Forge")
+all_data_forge <- left_join(all_data_forge, projects_topics, by = c("project_name" = "id"))
 save(all_data_forge, file = "gitlab_forge.RData")
-
diff --git a/global.R b/global.R
index 39979328479f751ed16fe486c5daa17f5155e480..d35e2cbf44e6982971b1f5d0700edaff8302e403 100644
--- a/global.R
+++ b/global.R
@@ -1,6 +1,6 @@
 # global -----
 # les packages nécessaire
-
+library(stringr)
 library(gitlabr)
 library(DT)
 library(shiny)
@@ -18,15 +18,29 @@ library(utils)
 library(lubridate)
 library(bizdays)
 library(shinyWidgets)
+library(textclean)
+library(stringi)
 # chargement des données (résultat du script "dev/script_chargement_rdata.R")
 load("github.RData")
 load("gitlab_forge.RData")
 load("gitlab.RData")
+load("date_MAJ.RData")
 
 all_data <- bind_rows(all_data_gitlab, all_data_forge, combined_data)
 all_data$updated_at <- as.POSIXct(all_data$updated_at, format = ("%Y-%m-%dT%H:%M:%S"))
-all_data <- all_data %>% mutate(message = paste0(type,sep = "  : ",message))
+all_data <- all_data %>% mutate(message = paste0(type,sep = "  : ",message),
+                                categorie = case_when(
+                                  str_detect(project_name, "parcours_r") ~ "r-formation",
+                                  str_detect(project_name, "spyrales") ~ "spyrales",
+                                  TRUE ~ "autre"
+                                ))
+# transformation author ----
+all_data$author <- all_data$author %>%
+  tolower() %>%
+  stri_trans_general("Latin-ASCII") %>%
+  str_replace_all("[^a-z ]", "")
 
+# transformation re_code ----
 traduction <- c(
   "commit" = "Code",
   "DiffNote" = "Code",
@@ -41,3 +55,7 @@ traduction <- c(
   "Milestone" = "Gestion de projet"
 )
 all_data <- all_data %>% dplyr::mutate(re_code = dplyr::recode(type , !!!traduction))
+
+#transformation message
+all_data$message <- all_data$message %>% tolower()
+min_all_data <- all_data %>% filter(str_detect(message,'commit  : initial commit'))
diff --git a/server.R b/server.R
index ed07b45c333e6b41c6d34c95deb54c1353cc2d2f..90e2c87d46b24bc2179e0858e4943cd631b397b2 100644
--- a/server.R
+++ b/server.R
@@ -1,99 +1,118 @@
-server <- function(input, output, session) {  # Ajout de `session` pour `updateSelectizeInput`
+server <- function(input, output, session) {
+  r <- reactiveValues(
+    filteredData = all_data,
+    filteredByProject = all_data, # Étape intermédiaire filtrée par daterange et project_name
+    filteredTopics = NULL,
+    filteredProjects = NULL,
+    filteredAuthors = NULL,
+    filteredReCodes = NULL,
+    filteredCategories = NULL,
+    filteredByDate = NULL,
+  )
 
-  # Initialisation des valeurs réactives
-  r <- reactiveValues(filteredData = NULL, filteredData2 = NULL)
-
-  # Daterange ----
+  # Filtrage par date et project_name uniquement
   observeEvent(input$daterange, {
     req(input$daterange)
-    r$filteredData <- all_data %>%
-      filter(updated_at >= as.Date(input$daterange[[1]]) &
-               updated_at <= as.Date(input$daterange[[2]]))
-
-    # Initialiser filteredData2 avec les mêmes valeurs que filteredData
-    r$filteredData2 <- r$filteredData
+    r$filteredByDate <- all_data %>%
+      filter(
+        updated_at >= as.Date(input$daterange[[1]]) &
+          updated_at <= as.Date(input$daterange[[2]]) &
+          (if (length(input$project_name)) project_name %in% input$project_name else TRUE)
+      )
+    updateFilters() # Mise à jour des choix basés sur le filtrage intermédiaire
+  })
 
-    # Mettre à jour les choix de projets
-    updateSelectizeInput(
-      session,
-      inputId = "idprojet",
-      label = "Projet : ",
-      choices = unique(r$filteredData$project_name)
-    )
+  # Mise à jour des autres filtres
+  observe({
+    req(input$daterange)
+    r$filteredData <- r$filteredByDate %>%
+      filter(
+        (if (length(input$topics)) sapply(input$topics, function(t) grepl(t, topics)) %>% rowSums() > 0 else TRUE) &
+          (if (length(input$author)) author %in% input$author else TRUE) &
+          (if (length(input$re_code)) re_code %in% input$re_code else TRUE) &
+          (if (length(input$categorie)) categorie %in% input$categorie else TRUE)
+      )
+    updateFilters()
   })
 
-  # Affichage du bouton de réinitialisation ----
-  output$button <- renderUI({
-    actionButton_dsfr("reset_button", "Réinitialiser les projets")
+  # Fonction de mise à jour des choix pour les filtres
+  updateFilters <- reactive({
+    # Basé sur les données filtrées par date et projet
+    updateSelectizeInput(session, "topics", choices = unique(r$filteredByDate$topics)%>%
+                           strsplit(split = ",") %>%  # Divise les chaînes en éléments séparés
+                           unlist() %>%               # Aplatit la liste obtenue
+                           na.omit() %>%              # Supprime les NA (au cas où)
+                           .[. != ""] %>%             # Supprime les chaînes vides
+                           trimws() %>%                # suppremie les espace avnt et apres
+                           unique() , selected = input$topics)
+    updateSelectizeInput(session, "author", choices = unique(r$filteredByDate$author), selected = input$author)
+    updateSelectizeInput(session, "categorie", choices = unique(r$filteredByDate$categorie), selected = input$categorie)
+
+    # Basé uniquement sur les données globales pour éviter que project_name soit affecté
+    updateSelectizeInput(session, "project_name", choices = sort(unique(r$filteredByDate$project_name)), selected = input$project_name)
   })
 
-  # Réinitialisation de input$idprojet lorsque le bouton est cliqué ----
-  observeEvent(input$reset_button, {
-    # Réinitialise la sélection de `idprojet` à vide
-    updateSelectizeInput(
-      session,
-      inputId = "idprojet",
-      selected = character(0)  # Met à vide `input$idprojet`
-    )
-    # Réinitialise `filteredData2` à toutes les données de `filteredData`
-    r$filteredData2 <- r$filteredData
+  # Réinitialisation des filtres
+  observeEvent(input$reset, {
+    r$filteredByDate <- all_data %>%
+      filter(updated_at >= as.Date(input$daterange[[1]]) &
+               updated_at <= as.Date(input$daterange[[2]]))
+    r$filteredData <- r$filteredByDate
+    updateSelectizeInput(session, "topics", selected = NULL)
+    updateSelectizeInput(session, "author", selected = NULL)
+    updateSelectizeInput(session, "categorie", selected = NULL)
+    updateFilters()
   })
+  output$lien <- renderUI({
+    projects_with_links <- r$filteredData %>%
+      filter(origine == "Gitlab_Forge" & project_name %in% input$project_name)
 
-  # Mise à jour de filteredData2 lorsque les projets sont sélectionnés/désélectionnés ----
-  observeEvent(input$idprojet, {
-    if (is.null(input$idprojet) || length(input$idprojet) == 0) {
-      # Si aucun projet n'est sélectionné, afficher tous les projets
-      r$filteredData2 <- r$filteredData
-    } else {
-      # Sinon, filtrer par projets sélectionnés
-      r$filteredData2 <- r$filteredData %>%
-        filter(project_name %in% input$idprojet)
+    if (nrow(projects_with_links) == 0) {
+      return(NULL) # Aucun lien à afficher
     }
 
-    # Générer l'interface des liens pour chaque projet
-    output$lien <- renderUI({
-      urls <- paste0("https://gitlab-forge.din.developpement-durable.gouv.fr/dreal-pdl/csd/", input$idprojet)
-      links <- lapply(seq_along(input$idprojet), function(i) {
-        a(href = urls[i], target = "_blank", input$idprojet[i])
-      })
-      do.call(tagList, c(links, list(br())))
+    urls <- paste0("https://gitlab-forge.din.developpement-durable.gouv.fr/dreal-pdl/csd/", projects_with_links$project_name)
+    links <- lapply(seq_along(unique(projects_with_links$project_name)), function(i) {
+      a(href = urls[i], target = "_blank", projects_with_links$project_name[i])
     })
+    do.call(tagList, links)
   })
 
-  # Graphique 1 basé sur filteredData ----
-  output$filteredPlot <- plotly::renderPlotly({
+  # Graphique interactif
+  output$filteredPlot2 <- plotly::renderPlotly({
     req(r$filteredData)
     p <- ggplot2::ggplot(r$filteredData, ggplot2::aes(x = updated_at, y = as.factor(project_name))) +
-      ggplot2::geom_jitter(ggplot2::aes(color = re_code, text = paste(updated_at, message, sep = "\n")),
-                           size = 3, alpha = 0.5,
-                           height = 0, width = 0.75) +
-      ggplot2::labs(shape = "re_code", color = "re_code", x = "") +
-      ggplot2::scale_x_datetime(date_labels = "%d/%m", timezone = "Europe/Paris") +
-      gouvdown::theme_gouv() +
-      ggplot2::theme(
-        axis.text.x = ggplot2::element_text(angle = 0, hjust = 1),
-        axis.title.y = ggplot2::element_blank()
-      ) +
-      gouvdown::scale_color_gouv_discrete(palette = "pal_gouv_qual2")
-
-    plotly::ggplotly(p, tooltip = "text")
-  })
-
-  # Graphique 2 basé sur filteredData2 ----
-  output$filteredPlot2 <- plotly::renderPlotly({
-    req(r$filteredData2)
-    p <- ggplot2::ggplot(r$filteredData2, ggplot2::aes(x = updated_at, y = as.factor(project_name))) +
       ggplot2::geom_point(ggplot2::aes(color = re_code, text = paste(updated_at, message, sep = "\n")),
                           size = 3, alpha = 0.5) +
-      ggplot2::labs(shape = "re_code", color = "re_code", x = "") +
+      ggplot2::labs(shape = "Événement", color = "Événement", x = "") +
       ggplot2::scale_x_datetime(timezone = "Europe/Paris") +
-      gouvdown::theme_gouv() +
+      gouvdown::theme_gouv()+
       ggplot2::theme(
         axis.text.x = ggplot2::element_text(angle = 0, hjust = 1),
         axis.title.y = ggplot2::element_blank()
-      ) +
-      gouvdown::scale_color_gouv_discrete(palette = "pal_gouv_qual2")
+      )
 
     plotly::ggplotly(p, tooltip = "text")
   })
+
+
+  output$table <- renderDataTable({
+    req(r$filteredData)
+    datatable(r$filteredData ,
+              options = list(
+                pageLength = 10,        # Nombre de lignes affichées par page
+                lengthMenu = c(5, 10, 25, 50),  # Choix du nombre de lignes
+                autoWidth = TRUE,        # Ajuste automatiquement la largeur des colonnes
+                scrollX = TRUE,          # Active le défilement horizontal
+                class = "display",       # Ajoute du style CSS
+                rownames = FALSE,         # Supprime les numéros de ligne,
+                searchHighlight = TRUE
+              )
+    )
+  })
+
+
+
+
+
 }
diff --git a/ui.R b/ui.R
index 1746958a6a5f98943ab052c1880d7bc014e058a9..5411578aa0bd77e044556d0ddd311d30b0ad0f28 100644
--- a/ui.R
+++ b/ui.R
@@ -1,4 +1,5 @@
-ui <- shinygouv::navbarPage_dsfr( # header & footer ------
+ui <- shinygouv::navbarPage_dsfr(
+  # header & footer ------
   title = "Dataviz GitlabR",
   id = "nav",
   header = shinygouv::header_dsfr(
@@ -16,32 +17,113 @@ ui <- shinygouv::navbarPage_dsfr( # header & footer ------
   # First tab Projet ---------
   shinygouv::navbarPanel_dsfr(
     title = "Graphique des projets par durée",
-    htmltools::HTML("</div><div class=\"fr-m-2w\">"),
+
+    htmltools::tags$head(tags$style(".fr-container { max-width: calc(100% - 2rem); }")),
     shinygouv::fluidRow_dsfr(
-      column_dsfr(2),
-      shinygouv::column_dsfr(4, shinygouv::dateRangeInput_dsfr(
-        inputId = "daterange",
-        label = "Sélectionnez une période :",
-        start = format(Sys.Date() - 7, format = "%Y-%m-%d"),
-        separator = "à"
+      shinygouv::column_dsfr(
+        3,
+        shinygouv::dateRangeInput_dsfr(
+          inputId = "daterange",
+          label = "Sélectionnez une période :",
+          start = format(Sys.Date() - 7, format = "%Y-%m-%d"),
+          separator = "à"
+        ),
+        extra_class = "fr-mt-6w"
+      ),
+      shinygouv::column_dsfr(
+        3,
+        selectizeInput(
+          inputId = "project_name",
+          label = "Projet : ",
+          choices = NULL,
+          multiple = TRUE
+        ),extra_class = "fr-mt-6w"
+      ),
+      column_dsfr(
+        3,
+        selectizeInput(
+          inputId = "topics",
+          label = "Étiquette :",
+          choices = all_data$topics %>%
+            strsplit(split = ",") %>%  # Divise les chaînes en éléments séparés
+            unlist() %>%               # Aplatit la liste obtenue
+            na.omit() %>%              # Supprime les NA (au cas où)
+            .[. != ""] %>%             # Supprime les chaînes vides
+            trimws() %>%                # suppremie les espace avnt et apres
+            unique() ,
+          # Extrait les éléments uniques
+          multiple = TRUE
+        ),extra_class = "fr-mt-6w"
+      ),
+      column_dsfr(
+        3,
+        selectizeInput(
+          inputId = "author",
+          label = "Auteur :",
+          choices = unique(str_to_title(replace_non_ascii(all_data$author))),
+          selected = NULL,
+          multiple = TRUE
+        ),extra_class = "fr-mt-6w"
+      ),
+      column_dsfr(
+        3,
+        actionButton_dsfr("reset", "Réinitialiser les projets"),
+        extra_class = "fr-my-2w"
+      ),
+      column_dsfr(
+        4,
+        checkboxGroupInput_dsfr(
+          inputId = "re_code",
+          label = "Type d'évènement :",
+          choices = unique(all_data$re_code),
+          inline = TRUE
+        )
       ),
-      extra_class = "fr-my-6w"),
-      shinygouv::column_dsfr(4,
-                             selectizeInput(inputId = "idprojet",label = "Projet : ",
-                                            choices = NULL, multiple = TRUE)),
-      column_dsfr(2),
-      column_dsfr(3),
-      column_dsfr(12,uiOutput("button")),
-      shinygouv::column_dsfr(9,uiOutput("lien"),extra_class = "fr-my-6w")
+      column_dsfr(
+        4,
+        selectizeInput(
+          inputId = "categorie",
+          label = "Groupe: ",
+          choices = c(
+            "Autre" = "tous",
+            "Spyrales" = "spyrale",
+            "R Formation" = "github"
+          ),
+          selected = NULL,
+          multiple = TRUE
+        )
       ),
-    tabsetPanel_dsfr("tableau_proj",
-    tabPanel_dsfr(id = "graph_input", title = "graphique par choix",
-                  shinygouv::fluidRow_dsfr(
-                    shinygouv::column_dsfr(12, plotly::plotlyOutput("filteredPlot2", height = "700px"),
-                                           extra_class = "fr-my-1w")
+      shinygouv::column_dsfr(9, uiOutput("lien"), extra_class = "fr-my-6w")
+    ),
+    tabsetPanel_dsfr(
+      "tableau_proj",
+      tabPanel_dsfr(
+        id = "graph_input",
+        title = "graphique par choix",
+        shinygouv::fluidRow_dsfr(
+          shinygouv::column_dsfr(
+            12,
+            plotly::plotlyOutput("filteredPlot2", height = "700px"),
+            extra_class = "fr-my-1w"
+          )
 
-                  )
-                  )# tab graphique par choix ↑
-  )#↑ tableau_proj
+        )
+      ),# tab graphique par choix ↑
+      tabPanel_dsfr(
+        id = "indicateur" ,
+        title = "Indicateurs",
+        shinygouv::fluidRow_dsfr(
+          shinygouv::column_dsfr(12)
+        )
+                    ),
+      tabPanel_dsfr(
+        id = "table" ,
+        title = "tableau",
+        shinygouv::fluidRow_dsfr(
+          shinygouv::column_dsfr(12,
+                                 DT::dataTableOutput("table"))
+        )
+        )
+    )#↑ tableau_proj
   )# ↑ Navbar
 )# ↑ UI