Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
1304 extensions - wrap repetitive code into modules (#1338)
This PR extends #1333 Starting a new PR against the feature branch in case my changes break pipelines. The current feature branch is green and working. The only thing we wanted to improve is the reduction of the repetitive code and inclusion of such code into modules. @gogonzo the last thing to discuss is whether we rename `srv_validate_teal_data` or `srv_validate_reactive_teal_data`. Maybe this discussion can be continued in here #1330 (comment) <details><summary>Tested with below code</summary> ```r pkgload::load_all("teal") # ░█──░█ ─█▀▀█ ░█─── ▀█▀ ░█▀▀▄ # ─░█░█─ ░█▄▄█ ░█─── ░█─ ░█─░█ # ──▀▄▀─ ░█─░█ ░█▄▄█ ▄█▄ ░█▄▄▀ # 1. Teal App with teal_data app <- init( data = teal_data(iris_raw = iris, mtcars = mtcars), modules = modules(example_module("Module 1"), example_module("Module 2")) ) shinyApp(app$ui, app$server) # 2. Teal App with teal_data_module app <- init( data = teal_data_module( ui = function(id) { actionButton(NS(id, "submit"), "Submit") }, server = function(id) { moduleServer(id, function(input, output, session) { eventReactive(input$submit, { teal_data(iris = iris, mtcars = mtcars) }) }) }, once = TRUE # also try once = FALSE ), modules = modules(example_module("Module 1"), example_module("Module 2")) ) shinyApp(app$ui, app$server) # 3. Teal Module with teal_data modules <- modules(example_module(), example_module("mtcars only", datanames = "mtcars")) ui <- fluidPage( "Custom UI", ui_teal(id = "teal_1", modules = modules), ui_teal(id = "teal_2", modules = modules) ) server <- function(input, output, session) { data <- teal_data(iris = iris, mtcars = mtcars) srv_teal(id = "teal_1", data = data, modules = modules) srv_teal(id = "teal_2", data = data, modules = modules) } shinyApp(ui, server) # 4. Teal Module with teal_data_module modules <- modules(example_module("Module 1"), example_module("Module 2")) data <- teal_data_module( ui = function(id) { actionButton(NS(id, "submit"), "Submit") }, server = function(id) { moduleServer(id, function(input, output, session) { eventReactive(input$submit, { teal_data(iris = iris, mtcars = mtcars) }) }) }, once = TRUE # also try once = FALSE ) ui <- fluidPage( "Custom UI", ui_teal(id = "teal1", data = data, modules = modules), ui_teal(id = "teal2", data = data, modules = modules) ) server <- function(input, output, session) { srv_teal(id = "teal1", data = data, modules = modules) srv_teal(id = "teal2", data = data, modules = modules) } shinyApp(ui, server) # 5. Teal Module with reactive(teal_data) modules <- modules(example_module("One"), example_module("Two")) ui <- fluidPage( selectInput("data", "Data", c("iris", "mtcars"), multiple = TRUE), ui_teal(id = "teal_1", modules = modules), ui_teal(id = "teal_2", modules = modules) ) server <- function(input, output, session) { data <- reactive({ req(input$data) within( teal_data(), { if ("iris" %in% selection) { iris <- iris } if ("mtcars" %in% selection) { mtcars <- mtcars } }, selection = input$data ) }) srv_teal(id = "teal_1", data = data, modules = modules) srv_teal(id = "teal_2", data = data, modules = modules) } shinyApp(ui, server) # ░█▀▀▀ ░█▀▀█ ░█▀▀█ ░█▀▀▀█ ░█▀▀█ # ░█▀▀▀ ░█▄▄▀ ░█▄▄▀ ░█──░█ ░█▄▄▀ # ░█▄▄▄ ░█─░█ ░█─░█ ░█▄▄▄█ ░█─░█ # 1. Teal App with teal_data app <- init( data = within(teal_data(), { stop("error") }), modules = modules(example_module("Module 1"), example_module("Module 2")) ) app <- init( data = teal_data(), modules = modules(example_module("Module 1"), example_module("Module 2")) ) # 2. Teal App with teal_data_module app <- init( data = teal_data_module( ui = function(id) { actionButton(NS(id, "submit"), "Submit") }, server = function(id) { moduleServer(id, function(input, output, session) { eventReactive(input$submit, { within( teal_data(), { iris <- head(iris, count) if (count %% 2 != 0) { stop("error") } mtcars <- mtcars }, count = input$submit ) }) }) }, once = FALSE ), modules = modules(example_module("Module 1"), example_module("Module 2")) ) shinyApp(app$ui, app$server) # 3. Teal Module with teal_data modules <- modules(example_module(), example_module("mtcars only", datanames = "mtcars")) ui <- fluidPage( "Custom UI", ui_teal(id = "teal_1", modules = modules), ui_teal(id = "teal_2", modules = modules) ) server <- function(input, output, session) { data <- teal_data(iris = iris, mtcars = mtcars) srv_teal( id = "teal_1", data = within(teal_data(), { stop("error") }), modules = modules ) srv_teal( id = "teal_2", data = within(teal_data(), { stop("error") }), modules = modules ) } shinyApp(ui, server) # 4. Teal Module with teal_data_module modules <- modules(example_module("Module 1"), example_module("Module 2")) data <- teal_data_module( ui = function(id) { actionButton(NS(id, "submit"), "Submit") }, server = function(id) { moduleServer(id, function(input, output, session) { eventReactive(input$submit, { within( teal_data(), { iris <- head(iris, count) if (count %% 2 != 0) { stop("error") } mtcars <- mtcars }, count = input$submit ) }) }) }, once = F ) ui <- fluidPage( "Custom UI", ui_teal(id = "teal", data = data, modules = modules) ) server <- function(input, output, session) { srv_teal(id = "teal", data = data, modules = modules) } shinyApp(ui, server) # 4. Teal Module with teal_data_module - DELEGATE THE DATANAMES VALIDATION AFTER TEAL TRANSFORM modules <- modules(example_module(datanames = "CO2"), example_module("Module 2")) data <- teal_data_module( ui = function(id) { actionButton(NS(id, "submit"), "Submit") }, server = function(id) { moduleServer(id, function(input, output, session) { eventReactive(input$submit, { within( teal_data(), { if (count %% 2 != 0) { CO2 <- CO2 } iris <- head(iris, count) mtcars <- mtcars }, count = input$submit ) }) }) }, once = FALSE ) ui <- fluidPage( "Custom UI", ui_teal(id = "teal", data = data, modules = modules) ) server <- function(input, output, session) { srv_teal(id = "teal", data = data, modules = modules) } shinyApp(ui, server) # 5. Teal Module with reactive(teal_data) - Error is not observed modules <- modules(example_module("One"), example_module("Two")) ui <- fluidPage( selectInput("data", "Data", c("iris", "mtcars"), multiple = TRUE), ui_teal(id = "teal_1", modules = modules), ui_teal(id = "teal_2", modules = modules) ) server <- function(input, output, session) { data <- reactive({ within( teal_data(), { if ("iris" %in% selection) { iris <- iris } else { stop("No iris is an error!") } if ("mtcars" %in% selection) { mtcars <- mtcars } }, selection = input$data ) }) srv_teal(id = "teal_1", data = data, modules = modules) srv_teal(id = "teal_2", data = data, modules = modules) } shinyApp(ui, server) ``` </details> <details><summary>Results of local tests</summary> ```r > options(TESTING_DEPTH = 5) > devtools::test() ℹ Testing teal [INFO] 2024-09-02 12:59:39.2876 pid:23540 token:[] teal You are using teal version 0.15.2.9059 ✔ | F W S OK | Context ✔ | 11 | init [1.0s] ✔ | 6 126 | module_teal [44.0s] ✔ | 95 | modules ✔ | 7 | rcode_utils ✔ | 8 | report_previewer_module ✔ | 6 | shinytest2-data_summary [38.5s] ✔ | 5 | shinytest2-filter_panel [40.7s] ✔ | 17 | shinytest2-init [24.2s] ✔ | 11 | shinytest2-landing_popup [41.1s] ✔ | 4 | shinytest2-module_bookmark_manager [35.4s] ✔ | 5 | shinytest2-modules [38.8s] ✔ | 8 | shinytest2-reporter [72.1s] ✔ | 9 | shinytest2-show-rcode [9.7s] ✔ | 9 | shinytest2-teal_data_module [57.1s] ✔ | 18 | shinytest2-teal_slices [61.3s] ✔ | 4 | shinytest2-utils [9.6s] ✔ | 4 | shinytest2-wunder_bar [18.9s] ✔ | 16 | teal_data_module-eval_code ✔ | 4 | teal_data_module ✔ | 25 | teal_reporter ✔ | 15 | teal_slices-store ✔ | 18 | teal_slices ✔ | 36 | utils [7.4s] ✔ | 17 | validate_has_data ✔ | 36 | validate_inputs ══ Results ══════════════════════════════════════════════════════════════════════════════════════════════════════════════════ Duration: 502.8 s ── Skipped tests (6) ──────────────────────────────────────────────────────────────────────────────────────────────────────── • need a fix in a .slicesGlobal (1): test-module_teal.R:1178:11 • todo (5): test-module_teal.R:1443:7, test-module_teal.R:1450:5, test-module_teal.R:1453:5, test-module_teal.R:1709:5, test-module_teal.R:1715:5 [ FAIL 0 | WARN 0 | SKIP 6 | PASS 514 ] ``` </details> --------- Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
- Loading branch information