Search code examples
rshinybslib

How to hide / show nav_panel based on user role


I have a shiny app using auth0 authentication and bslib framework, with three nav_panel() and a sidebar.

I want specific panels to be shown or hidden based on the logged-in users role. For example if the role is admin or coach then show Panel 2 and Panel 3, if the role is athlete then hide those two panels. I've tried conditionalPanel() but that doesnt seem to work.

here is a minimal reprex

library(shiny)
library(bslib)

ui <- page_navbar(
  title = "Panel Updates",
  sidebar = sidebar(
    id = "sidebar",
    "Sidebar"),
  nav_panel("Page 1", "Testing"),
  nav_panel("Page 2", "Availability"),
  nav_panel("Page 3", "Team"),
)

server <- function(input, output) {
  session$userData$auth0_info$`/roles` <- "athlete"
  output$role <- reactive({session$userData$auth0_info$`/roles`})
  outputOptions(output, 'role', suspendWhenHidden=FALSE)
  observe({print(userRole())})

shinyApp(ui, server)

Solution

  • You can use nav_hide() and nav_show() to control the visibility of the nav_panel()s.

    library(shiny)
    library(bslib)
    
    ROLES <- c("athlete", "coach", "admin")
    
    ui <- page_navbar(
      title = "Panel Updates",
      sidebar = sidebar(
        id = "sidebar",
        "Sidebar",
        radioButtons("role", "Role", choices = ROLES)
      ),
      id = "navbar",
      nav_panel("Page 1", "Testing"),
      nav_panel("Page 2", "Availability"),
      nav_panel("Page 3", "Team"),
    )
    
    server <- function(input, output, session) {
      role <- reactive({
        session$userData$auth0_info$`/roles` %||% input$role
      })
    
      observeEvent(role(), {
        if (role() %in% c("admin", "coach")) {
          nav_show("navbar", "Page 2")
          nav_show("navbar", "Page 3")
        } else if (role() == "athlete") {
          nav_hide("navbar", "Page 2")
          nav_hide("navbar", "Page 3")
        } else {
          stop(sprintf("user has unexpected role %s", role()))
        }
      })
    }
    
    shinyApp(ui, server)