Защитить модальный диалог в R Shiny - PullRequest
0 голосов
/ 18 июня 2020

Я работаю над общим обработчиком ошибок для большого приложения Shiny. Идея состоит в том, чтобы открыть модальное диалоговое окно с особым стилем в случае возникновения ошибки и таким образом уведомить пользователя о том, что что-то пошло не так. Поскольку приложение состоит из нескольких модулей, я думаю, что использование модального диалога в этом случае работает лучше всего.

В целом это уже работает нормально, но при открытии модального окна ошибки любой другой модальный код может перезаписать этот модальный диалог и, следовательно, пользователь может даже не осознавать, что произошла ошибка. Я не хочу останавливать выполнение приложения при возникновении ошибки, но хочу уведомить пользователя и дать ему возможность изменить ввод и повторить попытку.

Есть ли способ защитить модальное окно от перезаписи другими модальными окнами?

Ниже приведен минимальный пример. При выборе «успех» все отлично. Но при выборе «error» вы увидите только модальное окно ошибки из-за оператора Sys.sleep(). Без него он будет автоматически перезаписан.

library(shiny)

# load example functions to 
source("example-functions.R")


# define UI
ui <- fluidPage(
  # application title
  titlePanel("Error Handler"),

  # sidebar with controls 
  sidebarLayout(
    sidebarPanel(
      radioButtons(inputId = "expected_outcome",
                   label = "Expected Outcome",
                   choices = list("Success", 
                                  "Error")),
      actionButton(inputId = "btn_start",
                   label = "Execute Test")
    ),

    # result message in main panel
    mainPanel(
      textOutput("user_message")
    )
  )
)

# server logic
server <- function(input, output) {
  # define a symbol for reactive values
  rv <- reactiveValues()
  # define a reactive variable to display output in the UI and initialise it
  rv$user_message <- "Hello World!"


  # handler of the user message  
  output$user_message <- renderText({
    rv$user_message
  })


  observeEvent(input$btn_start, {
    message("Start Button was pressed")
    # initialise result variable with `NULL`
    result <- NULL

    if (input$expected_outcome == "Success") {
      # set UI text for success
      rv$user_message <- "Success!"
    } else {
      # set UI text for error
      rv$user_message <- "Error!"

      # show a special error modal
      showModal(
        div(
          id = "general-app-error",
          modalDialog(
            title = "An error occured.",
            "This is the error explanation"
          )
        )
      )
      # wait for a second to demonstrate the effect
      Sys.sleep(1)
    }


    # this modal should simulate that some other modal could come up and 
    # overwrite an error modal so the user will not realise that an error
    # happened.
    showModal(
      modalDialog(
        title = "App modal",
        "This is the app modal, possibly overwriting other modals.",
        size = "m"
      )
    )
  }, ignoreInit = TRUE)
}

# Run the application 
shinyApp(ui = ui, server = server)
...