Tychobra / polished

Authentication and Administration for Shiny apps
https://polished.tech
Other
233 stars 36 forks source link

Adding URI routing reloads the whole app when browser navigation is used #217

Closed kennedymwavu closed 1 year ago

kennedymwavu commented 1 year ago

By default, when using {polished}, the sign-in page has a URI with the query ?page=sign_in. I decided to add such routing to my app, and I noticed that the app works as expected without {polished}, with browser navigation (i.e., using the back and forward buttons) working properly. However, after adding {polished} authentication, using browser navigation causes the entire app to reload first, resulting in the loss of any uploaded data or selections made by the user.

Unless I'm missing something, this behavior appears to be a possible bug in {polished}.

Here is a reprex using navbarPage:

polished-uri-bug

ui.R

ui <- navbarPage(
  title = "Dashboard",
  id = "navbarID",
  footer = actionButton(inputId = "signout", label = "Sign Out"),
  tabPanel("Page 1", value = "page_1", "This is Page 1"),
  tabPanel("Page 2", value = "page_2", "This is Page 2"),
  tabPanel("Page 3", value = "page_3", "This is Page 3")
)

polished::secure_ui(ui)

server.R

server <- function(input, output, session){
  # sign out----
  observeEvent(input$signout, {
    polished::sign_out_from_shiny()
    session$reload()
  })

  # URI routing----
  observeEvent(getQueryString(session)$page, {
    currentQueryString <- getQueryString(session)$page
    if (is.null(input$navbarID) || !is.null(currentQueryString) && currentQueryString != input$navbarID) {
      freezeReactiveValue(input, "navbarID")
      updateNavbarPage(session, "navbarID", selected = currentQueryString)
    }
  }, priority = 1)

  observeEvent(input$navbarID, {
    currentQueryString <- getQueryString(session)$page
    pushQueryString <- paste0("?page=", input$navbarID)
    if (is.null(currentQueryString) || currentQueryString != input$navbarID) {
      freezeReactiveValue(input, "navbarID")
      updateQueryString(pushQueryString, mode = "push", session)
    }
  }, priority = 0)
}

polished::secure_server(server)

global.R

library(shiny)

# configure polished auth when the app initially starts up.
polished::polished_config(
  app_name = Sys.getenv("polished_app_name"),
  api_key = Sys.getenv("polished_api_key")
)
merlinoa commented 1 year ago

If you use something other than "page" (e.g. "tab") as your query param name, then I think it should be fine. The "page" query param is used by polished to navigate between sign in page, the app, and the admin panel which are actual separate shiny apps.

kennedymwavu commented 1 year ago

@merlinoa Thanks a lot for the clarification! Closing this now.