diff --git a/NEWS.md b/NEWS.md index 0cead9df67..bf541d8dab 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,7 +2,7 @@ ### Major breaking changes -* The use of `datasets` argument in `teal` `modules` has been deprecated and will be removed in a future release. Please use `data` argument instead. `data` is of type `tdata`; see "Creating custom modules" vignettes and function documentation of `teal::new_tdata` for further details. +* The use of `datasets` argument in `modules` has been deprecated and will be removed in a future release. Please use `data` argument instead. `data` is of type `tdata`; see "Creating custom modules" vignettes and function documentation of `teal::new_tdata` for further details. ### Breaking changes @@ -11,6 +11,7 @@ ### New features * Added the `validate_inputs` and `validate_inputs_segregated` functions that transfer input validation messages to app output. +* `modules` argument of `init` accepts `teal_module` type of object. There is no need to wrap up a single module in `modules()` or `list()`. ### Miscellaneous diff --git a/R/example_module.R b/R/example_module.R index b3cb8b7bcc..dcc5a0c73e 100644 --- a/R/example_module.R +++ b/R/example_module.R @@ -9,7 +9,7 @@ #' dataset("IRIS", iris), #' dataset("MTCARS", mtcars) #' ), -#' modules = modules(example_module()) +#' modules = example_module() #' ) #' if (interactive()) { #' shinyApp(app$ui, app$server) diff --git a/R/get_rcode.R b/R/get_rcode.R index ffe48a32e9..d32c726005 100644 --- a/R/get_rcode.R +++ b/R/get_rcode.R @@ -208,7 +208,7 @@ get_rcode_srv <- function(id, modal_title = "R Code", code_header = "Automatically generated R code", disable_buttons = reactiveVal(FALSE)) { - checkmate::check_class(disable_buttons, c("reactive", "function")) + checkmate::assert_class(disable_buttons, c("reactive", "function")) lifecycle::deprecate_warn( when = "0.12.1", diff --git a/R/init.R b/R/init.R index e455f0ada3..497c22d05e 100644 --- a/R/init.R +++ b/R/init.R @@ -23,8 +23,10 @@ #' NOTE: teal does not guarantee reproducibility of the code when names of the list elements #' do not match the original object names. To ensure reproducibility please use [teal.data::teal_data()] #' or [teal.data::cdisc_data()] with `check = TRUE` enabled. -#' @param modules (`list` or `teal_modules`)\cr -#' nested list of `teal_modules` or `module` objects. See [modules()] and [module()] for +#' @param modules (`list`, `teal_modules` or `teal_module`)\cr +#' nested list of `teal_modules` or `teal_module` objects or a single +#' `teal_modules` or `teal_module` object. These are the specific output modules which +#' will be displayed in the teal application. See [modules()] and [module()] for #' more details. #' @param title (`NULL` or `character`)\cr #' The browser window title (defaults to the host URL of the page). @@ -161,14 +163,16 @@ init <- function(data, checkmate::assert_string(title, null.ok = TRUE) checkmate::assert_class(data, "TealData") - checkmate::check_list(modules) - checkmate::check_class(modules, "teal_modules") + checkmate::assert_multi_class(modules, c("teal_module", "list", "teal_modules")) checkmate::assert_list(filter, min.len = 0, names = "unique") checkmate::assert_subset(names(filter), choices = teal.data::get_dataname(data)) checkmate::assert_character(id, max.len = 1, any.missing = FALSE) teal.logger::log_system_info() + if (is(modules, "teal_module")) { + modules <- list(modules) + } if (is(modules, "list")) { modules <- do.call(teal::modules, modules) } diff --git a/R/module_nested_tabs.R b/R/module_nested_tabs.R index 96576ad81c..d09c7dadbd 100644 --- a/R/module_nested_tabs.R +++ b/R/module_nested_tabs.R @@ -88,7 +88,7 @@ ui_nested_tabs.teal_modules <- function(id, modules, datasets, depth = 0L) { #' @export #' @keywords internal ui_nested_tabs.teal_module <- function(id, modules, datasets, depth = 0L) { - checkmate::check_class(datasets, "FilteredData") + checkmate::assert_class(datasets, "FilteredData") args <- isolate(teal.transform::resolve_delayed(modules$ui_args, datasets)) args <- c(list(id = id), args) diff --git a/R/module_tabs_with_filters.R b/R/module_tabs_with_filters.R index bc1ca784ad..81132bf2c0 100644 --- a/R/module_tabs_with_filters.R +++ b/R/module_tabs_with_filters.R @@ -14,6 +14,8 @@ #' panel is inserted at the right of the modules at depth 1 and not at the leaves. #' #' @inheritParams ui_teal_with_splash +#' @param modules (`teal_modules`) the modules which will be displayed in the teal application. +#' See [modules()] and [module()] for more details. #' @inheritParams init #' @param datasets (`FilteredData`)\cr #' object to store filter state and filtered datasets, shared across modules. For more diff --git a/R/module_teal_with_splash.R b/R/module_teal_with_splash.R index ae40a5d838..0171cee56b 100644 --- a/R/module_teal_with_splash.R +++ b/R/module_teal_with_splash.R @@ -48,6 +48,9 @@ ui_teal_with_splash <- function(id, #' Please also refer to the doc of [init()]. #' #' @inheritParams init +#' @param modules `teal_modules` object containing the output modules which +#' will be displayed in the teal application. See [modules()] and [module()] for +#' more details. #' @inheritParams shiny::moduleServer #' @return `reactive`, return value of [srv_teal()] #' @export diff --git a/R/modules_debugging.R b/R/modules_debugging.R index 91e60e354c..0f590d0479 100644 --- a/R/modules_debugging.R +++ b/R/modules_debugging.R @@ -27,9 +27,7 @@ #' ), #' code = "ADSL <- synthetic_cdisc_data(\"latest\")$adsl" #' ), -#' modules = modules( -#' teal:::filter_calls_module() -#' ), +#' modules = teal:::filter_calls_module(), #' header = "Simple teal app" #' ) #' if (interactive()) { diff --git a/man/example_module.Rd b/man/example_module.Rd index 19d6c718c6..ff276f1b4c 100644 --- a/man/example_module.Rd +++ b/man/example_module.Rd @@ -21,7 +21,7 @@ app <- init( dataset("IRIS", iris), dataset("MTCARS", mtcars) ), - modules = modules(example_module()) + modules = example_module() ) if (interactive()) { shinyApp(app$ui, app$server) diff --git a/man/filter_calls_module.Rd b/man/filter_calls_module.Rd index dc49091cb8..85889fac4d 100644 --- a/man/filter_calls_module.Rd +++ b/man/filter_calls_module.Rd @@ -29,9 +29,7 @@ app <- init( ), code = "ADSL <- synthetic_cdisc_data(\"latest\")$adsl" ), - modules = modules( - teal:::filter_calls_module() - ), + modules = teal:::filter_calls_module(), header = "Simple teal app" ) if (interactive()) { diff --git a/man/init.Rd b/man/init.Rd index 14f55d42db..f233171851 100644 --- a/man/init.Rd +++ b/man/init.Rd @@ -25,8 +25,10 @@ NOTE: teal does not guarantee reproducibility of the code when names of the list do not match the original object names. To ensure reproducibility please use \code{\link[teal.data:teal_data]{teal.data::teal_data()}} or \code{\link[teal.data:cdisc_data]{teal.data::cdisc_data()}} with \code{check = TRUE} enabled.} -\item{modules}{(\code{list} or \code{teal_modules})\cr -nested list of \code{teal_modules} or \code{module} objects. See \code{\link[=modules]{modules()}} and \code{\link[=module]{module()}} for +\item{modules}{(\code{list}, \code{teal_modules} or \code{teal_module})\cr +nested list of \code{teal_modules} or \code{teal_module} objects or a single +\code{teal_modules} or \code{teal_module} object. These are the specific output modules which +will be displayed in the teal application. See \code{\link[=modules]{modules()}} and \code{\link[=module]{module()}} for more details.} \item{title}{(\code{NULL} or \code{character})\cr diff --git a/man/modules_depth.Rd b/man/modules_depth.Rd index 85cfb7be75..d945fa439c 100644 --- a/man/modules_depth.Rd +++ b/man/modules_depth.Rd @@ -7,8 +7,10 @@ modules_depth(modules, depth = 0L) } \arguments{ -\item{modules}{(\code{list} or \code{teal_modules})\cr -nested list of \code{teal_modules} or \code{module} objects. See \code{\link[=modules]{modules()}} and \code{\link[=module]{module()}} for +\item{modules}{(\code{list}, \code{teal_modules} or \code{teal_module})\cr +nested list of \code{teal_modules} or \code{teal_module} objects or a single +\code{teal_modules} or \code{teal_module} object. These are the specific output modules which +will be displayed in the teal application. See \code{\link[=modules]{modules()}} and \code{\link[=module]{module()}} for more details.} \item{depth}{optional, integer determining current depth level} diff --git a/man/srv_nested_tabs.Rd b/man/srv_nested_tabs.Rd index 89ae7bdd3e..6d9e4e83af 100644 --- a/man/srv_nested_tabs.Rd +++ b/man/srv_nested_tabs.Rd @@ -31,8 +31,8 @@ is then preferred to this function.} object to store filter state and filtered datasets, shared across modules. For more details see \code{\link[teal.slice:FilteredData]{teal.slice::FilteredData}}.} -\item{modules}{(\code{list} or \code{teal_modules})\cr -nested list of \code{teal_modules} or \code{module} objects. See \code{\link[=modules]{modules()}} and \code{\link[=module]{module()}} for +\item{modules}{\code{teal_modules} object containing the output modules which +will be displayed in the teal application. See \code{\link[=modules]{modules()}} and \code{\link[=module]{module()}} for more details.} \item{reporter}{(\code{Reporter}) object from \code{teal.reporter}} diff --git a/man/srv_tabs_with_filters.Rd b/man/srv_tabs_with_filters.Rd index 5a3695ef37..e50098efea 100644 --- a/man/srv_tabs_with_filters.Rd +++ b/man/srv_tabs_with_filters.Rd @@ -23,8 +23,8 @@ is then preferred to this function.} object to store filter state and filtered datasets, shared across modules. For more details see \code{\link[teal.slice:FilteredData]{teal.slice::FilteredData}}.} -\item{modules}{(\code{list} or \code{teal_modules})\cr -nested list of \code{teal_modules} or \code{module} objects. See \code{\link[=modules]{modules()}} and \code{\link[=module]{module()}} for +\item{modules}{\code{teal_modules} object containing the output modules which +will be displayed in the teal application. See \code{\link[=modules]{modules()}} and \code{\link[=module]{module()}} for more details.} \item{reporter}{(\code{Reporter}) object from \code{teal.reporter}} diff --git a/man/srv_teal.Rd b/man/srv_teal.Rd index b1cd99094d..a6d631f181 100644 --- a/man/srv_teal.Rd +++ b/man/srv_teal.Rd @@ -13,8 +13,10 @@ the server function must be called with \code{\link[shiny:moduleServer]{shiny::m See the vignette for an example. However, \code{\link[=ui_teal_with_splash]{ui_teal_with_splash()}} is then preferred to this function.} -\item{modules}{(\code{list} or \code{teal_modules})\cr -nested list of \code{teal_modules} or \code{module} objects. See \code{\link[=modules]{modules()}} and \code{\link[=module]{module()}} for +\item{modules}{(\code{list}, \code{teal_modules} or \code{teal_module})\cr +nested list of \code{teal_modules} or \code{teal_module} objects or a single +\code{teal_modules} or \code{teal_module} object. These are the specific output modules which +will be displayed in the teal application. See \code{\link[=modules]{modules()}} and \code{\link[=module]{module()}} for more details.} \item{raw_data}{(\code{reactive})\cr diff --git a/man/srv_teal_with_splash.Rd b/man/srv_teal_with_splash.Rd index 2b76b6ca1b..f2701cb2fd 100644 --- a/man/srv_teal_with_splash.Rd +++ b/man/srv_teal_with_splash.Rd @@ -24,8 +24,8 @@ NOTE: teal does not guarantee reproducibility of the code when names of the list do not match the original object names. To ensure reproducibility please use \code{\link[teal.data:teal_data]{teal.data::teal_data()}} or \code{\link[teal.data:cdisc_data]{teal.data::cdisc_data()}} with \code{check = TRUE} enabled.} -\item{modules}{(\code{list} or \code{teal_modules})\cr -nested list of \code{teal_modules} or \code{module} objects. See \code{\link[=modules]{modules()}} and \code{\link[=module]{module()}} for +\item{modules}{\code{teal_modules} object containing the output modules which +will be displayed in the teal application. See \code{\link[=modules]{modules()}} and \code{\link[=module]{module()}} for more details.} \item{filter}{(\code{list})\cr diff --git a/man/ui_nested_tabs.Rd b/man/ui_nested_tabs.Rd index 49ce7d22de..9c86fcf67b 100644 --- a/man/ui_nested_tabs.Rd +++ b/man/ui_nested_tabs.Rd @@ -19,9 +19,8 @@ ui_nested_tabs(id, modules, datasets, depth = 0L) \item{id}{(\code{character(1)})\cr module id} -\item{modules}{(\code{list} or \code{teal_modules})\cr -nested list of \code{teal_modules} or \code{module} objects. See \code{\link[=modules]{modules()}} and \code{\link[=module]{module()}} for -more details.} +\item{modules}{(\code{teal_modules}) the modules which will be displayed in the teal application. +See \code{\link[=modules]{modules()}} and \code{\link[=module]{module()}} for more details.} \item{datasets}{(\code{FilteredData})\cr object to store filter state and filtered datasets, shared across modules. For more diff --git a/man/ui_tabs_with_filters.Rd b/man/ui_tabs_with_filters.Rd index 9b49723580..f0641913d5 100644 --- a/man/ui_tabs_with_filters.Rd +++ b/man/ui_tabs_with_filters.Rd @@ -10,9 +10,8 @@ ui_tabs_with_filters(id, modules, datasets) \item{id}{(\code{character(1)})\cr module id} -\item{modules}{(\code{list} or \code{teal_modules})\cr -nested list of \code{teal_modules} or \code{module} objects. See \code{\link[=modules]{modules()}} and \code{\link[=module]{module()}} for -more details.} +\item{modules}{(\code{teal_modules}) the modules which will be displayed in the teal application. +See \code{\link[=modules]{modules()}} and \code{\link[=module]{module()}} for more details.} \item{datasets}{(\code{FilteredData})\cr object to store filter state and filtered datasets, shared across modules. For more diff --git a/tests/testthat/test-init.R b/tests/testthat/test-init.R index e5f30ee060..90e4b36eef 100644 --- a/tests/testthat/test-init.R +++ b/tests/testthat/test-init.R @@ -129,3 +129,18 @@ testthat::test_that("init data accepts a list of TealDatasetConnector object", { NA ) }) + +testthat::test_that("init modules accepts a teal_modules object", { + mods <- modules(example_module(), example_module()) + testthat::expect_error(init(data = iris, modules = mods), NA) +}) + +testthat::test_that("init modules accepts a list of teal_module elements", { + mods <- list(example_module(), example_module()) + testthat::expect_error(init(data = iris, modules = mods), NA) +}) + +testthat::test_that("init modules accepts a teal_module object", { + mods <- example_module() + testthat::expect_error(init(data = iris, modules = mods), NA) +}) diff --git a/vignettes/adding-support-for-reporting.Rmd b/vignettes/adding-support-for-reporting.Rmd index af5695bfc7..8030594415 100644 --- a/vignettes/adding-support-for-reporting.Rmd +++ b/vignettes/adding-support-for-reporting.Rmd @@ -58,7 +58,7 @@ app <- init( dataset("IRIS", iris), dataset("MTCARS", mtcars) ), - modules = modules(teal_example_module()) + modules = teal_example_module() ) if (interactive()) shinyApp(app$ui, app$server) @@ -97,7 +97,7 @@ app <- init( dataset("IRIS", iris), dataset("MTCARS", mtcars) ), - modules = modules(example_module_with_reporting()) + modules = example_module_with_reporting() ) if (interactive()) shinyApp(app$ui, app$server) @@ -148,7 +148,7 @@ app <- init( dataset("IRIS", iris), dataset("MTCARS", mtcars) ), - modules = modules(example_module_with_reporting()) + modules = example_module_with_reporting() ) if (interactive()) shinyApp(app$ui, app$server) @@ -206,7 +206,7 @@ app <- init( dataset("IRIS", iris), dataset("MTCARS", mtcars) ), - modules = modules(example_module_with_reporting()) + modules = example_module_with_reporting() ) if (interactive()) shinyApp(app$ui, app$server) @@ -327,7 +327,7 @@ app <- init( dataset("IRIS", iris, code = "data(iris); IRIS <- iris"), check = FALSE ), - modules = modules( + modules = list( example_reporter_module(label = "with Reporter"), example_module(label = "without Reporter") ), diff --git a/vignettes/creating-custom-modules.Rmd b/vignettes/creating-custom-modules.Rmd index 381a311267..32f640b26b 100644 --- a/vignettes/creating-custom-modules.Rmd +++ b/vignettes/creating-custom-modules.Rmd @@ -190,14 +190,12 @@ app <- init( dataset("IRIS", iris, code = "IRIS <- iris"), check = TRUE ), - modules = modules( - tm_histogram_example( - label = "Simple Module", - histogram_var = data_extract_spec( - dataname = "IRIS", - select = select_spec( - choices = c("Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width") - ) + modules = tm_histogram_example( + label = "Simple Module", + histogram_var = data_extract_spec( + dataname = "IRIS", + select = select_spec( + choices = c("Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width") ) ) ), diff --git a/vignettes/including-adam-data-in-teal.Rmd b/vignettes/including-adam-data-in-teal.Rmd index a5dbb7a517..e5ed82db8d 100644 --- a/vignettes/including-adam-data-in-teal.Rmd +++ b/vignettes/including-adam-data-in-teal.Rmd @@ -83,7 +83,7 @@ example_data <- cdisc_data( app <- init( data = example_data, - modules = modules(example_module()) + modules = example_module() ) if (interactive()) { diff --git a/vignettes/including-general-data-in-teal.Rmd b/vignettes/including-general-data-in-teal.Rmd index 38d9a318be..793ef74b68 100644 --- a/vignettes/including-general-data-in-teal.Rmd +++ b/vignettes/including-general-data-in-teal.Rmd @@ -23,7 +23,7 @@ app <- init( dataset("IRIS", iris, code = "IRIS <- iris"), dataset("CARS", mtcars, code = "CARS <- mtcars") ), - modules = modules(example_module()) + modules = example_module() ) if (interactive()) { @@ -69,7 +69,7 @@ app <- init( fun_dataset_connector("PETS", fun = pet_generator, keys = "ID") ) %>% mutate_join_keys("PERSON", "PETS", c("ID" = "PERSON_ID")), - modules = modules(example_module()) + modules = example_module() ) if (interactive()) { diff --git a/vignettes/including-mae-data-in-teal.Rmd b/vignettes/including-mae-data-in-teal.Rmd index 2566801b6e..81e4432f3e 100644 --- a/vignettes/including-mae-data-in-teal.Rmd +++ b/vignettes/including-mae-data-in-teal.Rmd @@ -26,9 +26,7 @@ mae_d <- dataset("MAE", miniACC, metadata = list(type = "example")) app <- init( data = teal_data(mae_d), - modules = modules( - example_module() - ) + modules = example_module() ) if (interactive()) { diff --git a/vignettes/preprocessing-data.Rmd b/vignettes/preprocessing-data.Rmd index 4b0b6830bd..acbb5f1a96 100644 --- a/vignettes/preprocessing-data.Rmd +++ b/vignettes/preprocessing-data.Rmd @@ -41,7 +41,7 @@ cs_arm <- choices_selected(c("ACTARMCD", "ARMCD"), "ACTARMCD") app <- init( data = cdisc_data(cdisc_dataset("ADSL", adsl), code = get_code(file = "app.R")), - modules = modules(example_module()) + modules = example_module() ) shinyApp(app$ui, app$server) @@ -72,7 +72,7 @@ x <- init( code = get_code("app.R", exclude_comments = TRUE, read_sources = TRUE), check = TRUE ), - modules = modules(example_module()), + modules = example_module(), header = "Simple app with preprocessing", footer = tags$p(class = "text-muted", "Source: agile-R website") ) diff --git a/vignettes/teal-bs-themes.Rmd b/vignettes/teal-bs-themes.Rmd index 0483676b53..2c65fe1b0b 100644 --- a/vignettes/teal-bs-themes.Rmd +++ b/vignettes/teal-bs-themes.Rmd @@ -120,7 +120,7 @@ app <- init( dataset("IRIS", iris), dataset("MTCARS", mtcars) ), - modules = modules(example_module(), example_module()), + modules = list(example_module(), example_module()), header = "My first teal application" ) @@ -142,7 +142,7 @@ app <- init( dataset("IRIS", iris), dataset("MTCARS", mtcars) ), - modules = modules(example_module(), example_module()), + modules = list(example_module(), example_module()), header = "My first teal application" ) diff --git a/vignettes/teal.Rmd b/vignettes/teal.Rmd index 023f6ba5d4..33f1501ba6 100644 --- a/vignettes/teal.Rmd +++ b/vignettes/teal.Rmd @@ -41,7 +41,7 @@ app <- init( dataset("IRIS", iris), dataset("MTCARS", mtcars) ), - modules = modules(example_module()), + modules = example_module(), header = "My first teal application" )