Search code examples
rauthenticationshinysidebarshinyauthr

How to stop the sidebar appearing before shinyauthr authentication?


I'm using shinyauthr as a login for a shiny app. However, I get a small grey rectangle where the sidebar will appear, even before authentication (bottom left of the image).

enter image description here

How do I get the sidebar to appear only after authentication? Here's a simple app to demonstrate:

library(shiny)
library(shinyauthr)

user_base <- tibble::tibble(
  user = c("user1"),
  password = c("pass1"),
  permissions = c("admin"),
  name = c("User One")
)

ui <- fluidPage(
  div(class = "pull-right", shinyauthr::logoutUI(id = "logout")),
  shinyauthr::loginUI(id = "login"),
  sidebarLayout(
    sidebarPanel(uiOutput("sidebarpanel")),
    mainPanel(uiOutput("mainpanel"))
  )
)

server <- function(input, output, session) {
  
  credentials <- shinyauthr::loginServer(
    id = "login",
    data = user_base,
    user_col = user,
    pwd_col = password,
    log_out = reactive(logout_init())
  )
  
  logout_init <- shinyauthr::logoutServer(
    id = "logout",
    active = reactive(credentials()$user_auth)
  )
  
  output$sidebarpanel <- renderUI({
    req(credentials()$user_auth)
    tagList(
      numericInput("flank",
                   "Flank (bp)",
                   value = 110, min = 0, max = NA),
      numericInput("correction",
                   "Correction (repeats)",
                   value = 0, min = 0, max = NA)
    )
  })
  
  output$mainpanel <- renderTable({
    req(credentials()$user_auth)
    data.frame("Flank" = input$flank,
               "Correction" = input$correction)
  })
 
}
    
shinyApp(ui = ui, server = server)

Solution

  • You could wrap the two panels inside some div and assign ids to them:

    sidebarLayout(
        div(id = "sidebarPanel", sidebarPanel(uiOutput("sidebarpanel"))),
        div(id = "mainPanel", mainPanel(uiOutput("mainpanel")))
    )
    

    and then use an observe which contains a shinyjs::toggle depending on user_auth:

    observe({
        shinyjs::toggle(id = "sidebarPanel", condition = credentials()$user_auth)
        shinyjs::toggle(id = "mainPanel", condition = credentials()$user_auth)
    })
    

    Here is a complete example.

    library(shiny)
    library(shinyauthr)
    library(shinyjs)
    
    user_base <- tibble::tibble(
        user = c("user1"),
        password = c("pass1"),
        permissions = c("admin"),
        name = c("User One")
    )
    
    ui <- fluidPage(
        shinyjs::useShinyjs(),
        div(class = "pull-right", shinyauthr::logoutUI(id = "logout")),
        shinyauthr::loginUI(id = "login"),
        sidebarLayout(
            div(id = "sidebarPanel", sidebarPanel(uiOutput("sidebarpanel"))),
            div(id = "mainPanel", mainPanel(uiOutput("mainpanel")))
        )
    )
    
    server <- function(input, output, session) {
        
        credentials <- shinyauthr::loginServer(
            id = "login",
            data = user_base,
            user_col = user,
            pwd_col = password,
            log_out = reactive(logout_init())
        )
        
        logout_init <- shinyauthr::logoutServer(
            id = "logout",
            active = reactive(credentials()$user_auth)
        )
        
        observe({
            shinyjs::toggle(id = "sidebarPanel", condition = credentials()$user_auth)
            shinyjs::toggle(id = "mainPanel", condition = credentials()$user_auth)
        })
        
        output$sidebarpanel <- renderUI({
            req(credentials()$user_auth)
            tagList(
                numericInput("flank",
                             "Flank (bp)",
                             value = 110, min = 0, max = NA),
                numericInput("correction",
                             "Correction (repeats)",
                             value = 0, min = 0, max = NA)
            )
        })
        
        output$mainpanel <- renderTable({
            req(credentials()$user_auth)
            data.frame("Flank" = input$flank,
                       "Correction" = input$correction)
        })
        
    }
    
    shinyApp(ui = ui, server = server)