library(dplyr, quietly = TRUE, warn.conflicts = FALSE)
library(rmarkdown, quietly = TRUE, warn.conflicts = FALSE)
Curso <- tibble(Curso_id           = 1:4,
                 Curso_nome         = paste("Curso", LETTERS[1:4]),
                 Data_ininio          = seq.Date(from = lubridate::as_date("2021-01-01"), by = "month", length.out = 4),
                 Data_termino            = lubridate::ceiling_date(Data_ininio, unit = "month") - 1)

paged_table(Curso)
set.seed(42)
Aluno <- tibble(Aluno_id      = 1:20,
                  nome_abrev    = paste("Aluno", LETTERS[1:20]),
                  Genero    = sample(c("X","Y","Z"), 20, replace = TRUE),
                  Idade       = sample(18:35, 20, replace = TRUE),
                  Curso_id = sample(1:4, 20, replace = TRUE))

paged_table(Aluno)
df_combinado <- left_join(Curso, Aluno, by = "Curso_id")

paged_table(df_combinado)
library(reactable, quietly = TRUE, warn.conflicts = FALSE)

reactable(data = df_combinado)
reactable(
  data       = df_combinado,
  compact    = TRUE, # para altura mínima da linha
  filterable = TRUE, # para filtros de coluna individual
  striped    = TRUE, # linhas em faixas
  resizable  = TRUE, # para larguras de coluna redimensionáveis
  columns    = list( # definir o nome do cabeçalho personalizado, largura, alinhamento etc
    Curso_id   = colDef(name = "CID",         width = 50,  align = "center"),
    Curso_nome = colDef(name = "Nome Curso", width = 140),
    Data_ininio  = colDef(name = "Data Inicio",  width = 120, align = "center"),
    Data_termino    = colDef(name = "Data Fim",    width = 120, align = "center"),
    Aluno_id        = colDef(name = "AID",         width = 70,  align = "center"),
    nome_abrev      = colDef(name = "Nome Aluno"),
    Genero      = colDef(name = "Genero",      width = 80,  align = "center"),
    Idade         = colDef(name = "Idade",         width = 50)
  )
)
reactable(
  data       = df_combinado,
  compact    = TRUE, # para altura mínima da linha
  filterable = TRUE, # para filtros de coluna individual
  striped    = TRUE, # linhas em faixas
  resizable  = TRUE, # para larguras de coluna redimensionáveis
  groupBy    = "Curso_id",
  columns    = list(
    # mostrar contagem de Alunos em cada Curso
    Curso_id   = colDef(name = "CID",         width = 100,  align = "left",    aggregate = "count"),  
    # mostrar Nome Curso
    Curso_nome = colDef(name = "Nome Curso", width = 140,                     aggregate = "unique"), 
    # mostrar dados únicos de Inicio
    Data_ininio  = colDef(name = "Data Inicio",  width = 120,  align = "center",  aggregate = "unique"), 
    # mostrar dados únicos de Fim
    Data_termino    = colDef(name = "Data Fim",    width = 120,  align = "center",  aggregate = "unique"), 
    Aluno_id        = colDef(name = "AID",         width = 70,   align = "center"),
    nome_abrev      = colDef(name = "Nome Aluno"),
    Genero      = colDef(name = "Genero",      width = 80,   align = "center"),
    Idade         = colDef(name = "Idade",         width = 50)
  )
)
reactable(
  data       = df_combinado,
  compact    = TRUE, # para altura mínima da linha
  filterable = TRUE, # para filtros de coluna individual
  striped    = TRUE, # linhas em faixas
  resizable  = TRUE, # para larguras de coluna redimensionáveis
  groupBy    = "Curso_id",
  columns    = list(
    Curso_id   = colDef(name = "CID",         width = 100,  align = "left",    aggregate = "count"),
    Curso_nome = colDef(name = "Nome Curso", width = 140,                     aggregate = "unique"),
    Data_ininio  = colDef(name = "Data Inicio",  width = 120,  align = "center",  aggregate = "unique"),
    Data_termino    = colDef(name = "Data Fim",    width = 120,  align = "center",  aggregate = "unique"),
    # Agregando Aluno ID para mostrar ids únicos em cada Curso.
    Aluno_id        = colDef(name = "AID",         width = 70,   align = "center",  aggregate = "unique"), 
    nome_abrev      = colDef(name = "Nome Aluno"),
    Genero      = colDef(name = "Genero",      width = 80,   align = "center"),
    Idade         = colDef(name = "Idade",         width = 50)
  )
)
top_level <- df_combinado %>% 
  # Apenas colunas de informações do Curso
  count(Curso_id, Curso_nome, Data_ininio, Data_termino, name = "n_Alunos") 

paged_table(top_level)
segundo_nivel <- df_combinado %>% 
  # Apenas colunas de informação Aluno com identificador único para Curso
  select(Curso_id, Aluno_id, nome_abrev, Genero, Idade) %>% 
  arrange(Aluno_id)

paged_table(segundo_nivel)
reactable(
  data       = top_level,
  compact    = TRUE, # para altura mínima da linha
  filterable = TRUE, # para filtros de coluna individual
  striped    = TRUE, # linhas em faixas
  resizable  = TRUE, # para larguras de coluna redimensionáveis
  columns    = list(
    Curso_id   = colDef(name = "CID",             width = 50,  align = "center"),
    Curso_nome = colDef(name = "Nome Curso"), 
    Data_ininio  = colDef(name = "Data Inicio",      width = 120, align = "center"),
    Data_termino    = colDef(name = "Data Fim",        width = 120, align = "center"),
    n_Alunos  = colDef(name = "No. de Alunos", width = 130, align = "center")
  ),
  details = function(index) { # index é o número da linha da linha atual.
    # subtabela apenas daqueles alunos para a linha atual.
    sec_lvl = segundo_nivel[segundo_nivel$Curso_id == top_level$Curso_id[index], ] 
    reactable(data       = sec_lvl,
              compact    = TRUE, 
              filterable = TRUE,
              bordered   = TRUE, 
              resizable  = TRUE,
              columns    = list(
                Curso_id   = colDef(show = FALSE), # ocultar a coluna do ID do Curso
                Aluno_id        = colDef(name = "AID",    width = 70, align = "center"),
                nome_abrev      = colDef(name = "Nome Aluno"),
                Genero      = colDef(name = "Genero", width = 90, align = "center"),
                Idade         = colDef(name = "Idade",    width = 50, align = "center")
              )
              )
  }
)