feat: Implement a cancel button on the loading overlay to allow users to stop data fetching.
Browse files
server.R
CHANGED
|
@@ -488,6 +488,9 @@ server <- function(input, output, session) {
|
|
| 488 |
|
| 489 |
reset_fetch <- function(msg = NULL) {
|
| 490 |
fetch_stage(0)
|
|
|
|
|
|
|
|
|
|
| 491 |
loading_status(FALSE)
|
| 492 |
if (!is.null(msg)) loading_diagnostics(msg)
|
| 493 |
tmp <- fetch_temp_file()
|
|
@@ -498,6 +501,11 @@ server <- function(input, output, session) {
|
|
| 498 |
session$sendCustomMessage("unfreezeUI", list())
|
| 499 |
}
|
| 500 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 501 |
# Stage 1: Initialization
|
| 502 |
observe({
|
| 503 |
req(window_debounced()$id, window_debounced()$start, window_debounced()$end)
|
|
|
|
| 488 |
|
| 489 |
reset_fetch <- function(msg = NULL) {
|
| 490 |
fetch_stage(0)
|
| 491 |
+
# Invalidate token to kill pending async tasks
|
| 492 |
+
fetch_current_token(as.numeric(Sys.time()))
|
| 493 |
+
|
| 494 |
loading_status(FALSE)
|
| 495 |
if (!is.null(msg)) loading_diagnostics(msg)
|
| 496 |
tmp <- fetch_temp_file()
|
|
|
|
| 501 |
session$sendCustomMessage("unfreezeUI", list())
|
| 502 |
}
|
| 503 |
|
| 504 |
+
# Handle Cancel from Freeze Window
|
| 505 |
+
observeEvent(input$cancel_loading, {
|
| 506 |
+
reset_fetch("Cancelled by user")
|
| 507 |
+
})
|
| 508 |
+
|
| 509 |
# Stage 1: Initialization
|
| 510 |
observe({
|
| 511 |
req(window_debounced()$id, window_debounced()$start, window_debounced()$end)
|
ui.R
CHANGED
|
@@ -28,6 +28,7 @@ ui <- page_navbar(
|
|
| 28 |
justify-content: center;
|
| 29 |
}
|
| 30 |
.frozen-overlay-content {
|
|
|
|
| 31 |
background: white;
|
| 32 |
width: 400px;
|
| 33 |
min-height: 200px;
|
|
@@ -50,6 +51,20 @@ ui <- page_navbar(
|
|
| 50 |
font-size: 1.1rem;
|
| 51 |
color: #333;
|
| 52 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 53 |
/* Disable pointer events on sidebar when frozen */
|
| 54 |
body.ui-frozen .bslib-sidebar-layout > .sidebar {
|
| 55 |
pointer-events: none;
|
|
@@ -127,6 +142,11 @@ ui <- page_navbar(
|
|
| 127 |
$(document).on('hidden.bs.modal', '.modal', function () {
|
| 128 |
Shiny.setInputValue('modal_closed', new Date().getTime(), {priority: 'event'});
|
| 129 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 130 |
});
|
| 131 |
|
| 132 |
function toggleFullScreen() {
|
|
@@ -159,6 +179,7 @@ ui <- page_navbar(
|
|
| 159 |
class = "frozen-overlay",
|
| 160 |
div(
|
| 161 |
class = "frozen-overlay-content",
|
|
|
|
| 162 |
div(class = "spinner-border text-primary", role = "status"),
|
| 163 |
p(class = "frozen-overlay-message", "Loading data...")
|
| 164 |
)
|
|
|
|
| 28 |
justify-content: center;
|
| 29 |
}
|
| 30 |
.frozen-overlay-content {
|
| 31 |
+
position: relative;
|
| 32 |
background: white;
|
| 33 |
width: 400px;
|
| 34 |
min-height: 200px;
|
|
|
|
| 51 |
font-size: 1.1rem;
|
| 52 |
color: #333;
|
| 53 |
}
|
| 54 |
+
.frozen-overlay-close {
|
| 55 |
+
position: absolute;
|
| 56 |
+
top: 10px;
|
| 57 |
+
right: 15px;
|
| 58 |
+
border: none;
|
| 59 |
+
background: none;
|
| 60 |
+
font-size: 1.5rem;
|
| 61 |
+
color: #666;
|
| 62 |
+
cursor: pointer;
|
| 63 |
+
line-height: 1;
|
| 64 |
+
}
|
| 65 |
+
.frozen-overlay-close:hover {
|
| 66 |
+
color: #000;
|
| 67 |
+
}
|
| 68 |
/* Disable pointer events on sidebar when frozen */
|
| 69 |
body.ui-frozen .bslib-sidebar-layout > .sidebar {
|
| 70 |
pointer-events: none;
|
|
|
|
| 142 |
$(document).on('hidden.bs.modal', '.modal', function () {
|
| 143 |
Shiny.setInputValue('modal_closed', new Date().getTime(), {priority: 'event'});
|
| 144 |
});
|
| 145 |
+
|
| 146 |
+
// Handle freeze window close
|
| 147 |
+
$(document).on('click', '.frozen-overlay-close', function () {
|
| 148 |
+
Shiny.setInputValue('cancel_loading', new Date().getTime(), {priority: 'event'});
|
| 149 |
+
});
|
| 150 |
});
|
| 151 |
|
| 152 |
function toggleFullScreen() {
|
|
|
|
| 179 |
class = "frozen-overlay",
|
| 180 |
div(
|
| 181 |
class = "frozen-overlay-content",
|
| 182 |
+
tags$button(class = "frozen-overlay-close", "×", title = "Cancel loading"),
|
| 183 |
div(class = "spinner-border text-primary", role = "status"),
|
| 184 |
p(class = "frozen-overlay-message", "Loading data...")
|
| 185 |
)
|