Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Add busy indication#4040

Merged
cpsievert merged 36 commits intomainfrom
busy-indicators
May 10, 2024
Merged

Add busy indication#4040
cpsievert merged 36 commits intomainfrom
busy-indicators

Conversation

@cpsievert
Copy link
Collaborator

@cpsievert cpsievert commented May 2, 2024

This PR bring busy indication to Shiny. Busy indicators provide a visual cue to users when the server is busy calculating outputs or otherwise serving requests to the client. When enabled, a spinner is shown on each
calculating/recalculating output, and a pulsing banner is shown at the top of the page when the app is otherwise busy. Busy indicators will be enabled by default for UI created with {bslib} (rstudio/bslib#1053), but must be enabled otherwise. To enable/disable, include the result of useBusyIndicators() in anywhere in the app's UI.

Here is an illustration of the default spinner and pulse experience:

busy.mp4
App code
library(shiny)
library(bslib)

app <- page_sidebar(
  title = "Busy indicators demo",
  sidebar = list(
    selectInput(
      "indicator_types",
      "Busy indicator types",
      c("spinners", "pulse"),
      multiple = TRUE,
      selected = c("spinners", "pulse")
    ),
    downloadButton("download", "Download")
  ),
  # input_dark_mode(),
  card(
    card_header(
      "Plot that takes a few seconds to render",
      actionButton("simulate", "Simulate"),
      class = "d-flex justify-content-between align-items-center"
    ),
    plotOutput("plot")
  ),
  useBusyIndicators(),
  uiOutput("indicator_types_ui")
)


server <- function(input, output, session) {

  output$plot <- renderPlot({
    input$simulate
    Sys.sleep(3)
    plot(1:100, rnorm(100))
  })

  output$indicator_types_ui <- renderUI({
    useBusyIndicators(
      spinners = "spinners" %in% input$indicator_types,
      pulse = "pulse" %in% input$indicator_types
    )
  })

  output$download <- downloadHandler(
    filename = function() {
      paste("data-", Sys.Date(), ".csv", sep="")
    },
    content = function(file) {
      Sys.sleep(4)
      write.csv(mtcars, file)
    }
  )

}

shinyApp(app, server)

This PR also adds busyIndicatorOptions() to customize the appearance of both spinners and the pulse. Here's an example showing off 4 of the main spinner_types available: ring, bars, dots, and pulse.

spinner-types.mp4
App code
library(shiny)
library(bslib)

card_ui <- function(id, spinner_type = id) {
  card(
    busyIndicatorOptions(
      spinner_type = spinner_type,
      spinner_selector = NA
    ),
    card_header(paste("Spinner:", spinner_type)),
    plotOutput(shiny::NS(id, "plot"))
  )
}

card_server <- function(id, simulate = reactive()) {
  moduleServer(
    id = id,
    function(input, output, session) {
      output$plot <- renderPlot({
        Sys.sleep(1)
        simulate()
        plot(x = rnorm(100), y = rnorm(100))
      })
    }
  )
}

ui <- page_fillable(
  useBusyIndicators(),
  input_task_button("simulate", "Simulate", icon = icon("refresh")),
  layout_columns(
    card_ui("ring"),
    card_ui("bars"),
    card_ui("dots"),
    card_ui("pulse"),
    col_widths = 6
  )
)

server <- function(input, output, session) {
  simulate <- reactive(input$simulate)
  card_server("ring", simulate)
  card_server("bars", simulate)
  card_server("dots", simulate)
  card_server("pulse", simulate)
}

shinyApp(ui, server)

TODO

Base automatically changed from output-progress-state to main May 2, 2024 23:01
cpsievert added 2 commits May 3, 2024 09:46
…can't be trusted to show them when animated"

This reverts commit 6167c1d.
@cpsievert cpsievert marked this pull request as ready for review May 3, 2024 19:14
@cpsievert cpsievert requested a review from gadenbuie May 3, 2024 19:14
Copy link
Member

@gadenbuie gadenbuie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent PR! This review is all mostly small stuff and only from reading through the code. I'm looking forward to playing with this, but feel confident we can easily address follow up issues as they arise.

One more small note: I do think we should follow up relatively quickly with an alternate spinner option as well as a clear path for providing custom spinners.

@cpsievert cpsievert force-pushed the busy-indicators branch 3 times, most recently from 9bf81b1 to 7c23967 Compare May 9, 2024 22:40
@cpsievert cpsievert merged commit 3d66940 into main May 10, 2024
@cpsievert cpsievert deleted the busy-indicators branch May 10, 2024 19:58
cpsievert added a commit that referenced this pull request Jul 24, 2024
…fade` (#4104)

* Follow up to #4040: enable busy indicators by default

* Make our spinner invisible when wrapped inside a shinycssloaders::withSpinner() container

* Add the ability to disable/customize recalculating opacity (i.e., fade)

* Fix bug with fade not being applied correctly when the output container has no children

* `devtools::document()` (GitHub Actions)

* `yarn build` (GitHub Actions)

* Update NEWS.md

* Follow up to b7e7af: need to also rest opacity for :empty case (for initial calculation)

* Rd docs fixes/improvements

---------

Co-authored-by: cpsievert <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants