Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add teal app modifiers and deprecate init args #1440

Merged
merged 52 commits into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from 41 commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
b410a2f
feat: add teal app modifiers and deprecate init args
vedhav Jan 7, 2025
65a7e10
docs: add pkgdown index for the new functions
vedhav Jan 7, 2025
7063e66
feat: add a modifier for landing popup
vedhav Jan 8, 2025
029b24e
chore: change the depreciation message for landing popup
vedhav Jan 8, 2025
404dbd6
feat: modify using functions
vedhav Jan 10, 2025
aa60c14
chore: minor doc changes
vedhav Jan 10, 2025
f5cf6a5
docs: add news and update init
vedhav Jan 10, 2025
8f761d4
@gogonzo comments
vedhav Jan 10, 2025
0af8a67
improvements from @gogonzo
vedhav Jan 10, 2025
e6acc98
feat: modify the TealAppDriver args
vedhav Jan 10, 2025
66fb1aa
fix: maks sure the chromote app runs
vedhav Jan 10, 2025
9019c6e
fix: update the tests based on new TealAppDriver
vedhav Jan 10, 2025
c51ac21
Update R/init.R
vedhav Jan 10, 2025
2f4eb70
Update R/init.R
vedhav Jan 13, 2025
c652693
Update R/init.R
vedhav Jan 13, 2025
858c1a7
Update R/init.R
vedhav Jan 13, 2025
3d84da6
Update R/init.R
vedhav Jan 13, 2025
104aa9c
Update R/init.R
vedhav Jan 13, 2025
daa4a3d
Update _pkgdown.yml
vedhav Jan 13, 2025
9c648f2
Update R/init.R
vedhav Jan 13, 2025
4962e28
Update R/init.R
vedhav Jan 13, 2025
ab6e3fd
fix: fix the broken test
vedhav Jan 13, 2025
8633127
chore: add missing args to deprecated args
vedhav Jan 13, 2025
140eed7
Merge branch 'main' into 1310-simplify-init-args
vedhav Jan 13, 2025
08869e5
chore: stop using `build_app_title`
vedhav Jan 13, 2025
db3def8
[skip roxygen] [skip vbump] Roxygen Man Pages Auto Update
github-actions[bot] Jan 13, 2025
d35ed92
docs: add a vignette and update docs
vedhav Jan 13, 2025
5e53f1f
chore: fix spellcheck
vedhav Jan 13, 2025
cfe628e
@gogonzo comments + doc changes
vedhav Jan 13, 2025
d8eb34d
chore: doc changes
vedhav Jan 13, 2025
56896bc
@gogonzo comments
vedhav Jan 13, 2025
13b24b8
fix: fix the module server call with name-space
vedhav Jan 13, 2025
63065f0
chore: fix CI
vedhav Jan 13, 2025
8e4ad57
feat: add `teal_replace_ui` and generalize the UI replacements
vedhav Jan 15, 2025
ff480f9
[skip style] [skip vbump] Restyle files
github-actions[bot] Jan 15, 2025
160874c
feat: separate the sessioninfo module and remove unwanted ui from mod…
vedhav Jan 17, 2025
d615693
Merge branch 'main' into 1310-simplify-init-args
vedhav Jan 17, 2025
78b61a4
chore: doc changes
vedhav Jan 17, 2025
1f68edc
chore: fix pkgdown render + remove server modification from vignette
vedhav Jan 17, 2025
a6d20bc
docs: update the app screenshot as custom server is not exported
vedhav Jan 17, 2025
548daea
docs: remove exmple
vedhav Jan 17, 2025
46af6aa
chore: fix module_teal_with_splash
vedhav Jan 17, 2025
a442218
chore: rearrange docs
vedhav Jan 17, 2025
f421847
chore: update news and pass spellcheck
vedhav Jan 17, 2025
d49392b
@gogonzo comments
vedhav Jan 17, 2025
e339218
Update R/teal_modifiers.R
vedhav Jan 17, 2025
ed4bb57
chore: fix ns in test
vedhav Jan 17, 2025
842c189
chore: minor doc change
vedhav Jan 17, 2025
0e86236
chore: update module_teal docs
vedhav Jan 17, 2025
d50f579
chore: update doc
vedhav Jan 17, 2025
489a28c
chore: doc fixes
vedhav Jan 17, 2025
62e836f
docs: remove quick start guide vignette
vedhav Jan 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ repos:
- mirai
- checkmate
- cli
- htmltools
- jsonlite
- lifecycle
- logger
Expand Down
7 changes: 5 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,14 @@ URL: https://insightsengineering.github.io/teal/,
https://github.com/insightsengineering/teal/
BugReports: https://github.com/insightsengineering/teal/issues
Depends:
R (>= 4.0),
R (>= 4.1),
shiny (>= 1.8.1),
teal.data (>= 0.6.0.9017),
teal.slice (>= 0.5.1.9015)
Imports:
checkmate (>= 2.1.0),
cli,
htmltools,
jsonlite,
lifecycle (>= 0.2.0),
logger (>= 0.2.0),
Expand Down Expand Up @@ -84,7 +85,7 @@ Config/Needs/verdepcheck: rstudio/shiny, insightsengineering/teal.data,
rstudio/bslib, yihui/knitr, bioc::MultiAssayExperiment, r-lib/R6,
rstudio/rmarkdown, tidyverse/rvest, rstudio/shinytest2,
rstudio/shinyvalidate, r-lib/testthat, r-lib/withr,
yaml=vubiostat/r-yaml
yaml=vubiostat/r-yaml, rstudio/htmltools
Config/Needs/website: insightsengineering/nesttemplate
Encoding: UTF-8
Language: en-US
Expand All @@ -106,6 +107,7 @@ Collate:
'module_filter_manager.R'
'module_init_data.R'
'module_nested_tabs.R'
'module_session_info.R'
'module_snapshot_manager.R'
'module_teal.R'
'module_teal_data.R'
Expand All @@ -120,6 +122,7 @@ Collate:
'teal_data_module-eval_code.R'
'teal_data_module-within.R'
'teal_data_utils.R'
'teal_modifiers.R'
'teal_reporter.R'
'teal_slices-store.R'
'teal_slices.R'
Expand Down
6 changes: 6 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ S3method(ui_teal_module,teal_module)
S3method(ui_teal_module,teal_modules)
S3method(within,teal_data_module)
export(TealReportCard)
export(add_landing_popup)
export(as.teal_slices)
export(as_tdata)
export(build_app_title)
Expand All @@ -23,19 +24,24 @@ export(get_metadata)
export(init)
export(landing_popup_module)
export(make_teal_transform_server)
export(modify_footer)
export(modify_header)
export(modify_title)
export(module)
export(modules)
export(new_tdata)
export(report_card_template)
export(reporter_previewer_module)
export(show_rcode_modal)
export(srv_session_info)
vedhav marked this conversation as resolved.
Show resolved Hide resolved
export(srv_teal)
export(srv_teal_with_splash)
export(srv_transform_teal_data)
export(tdata2env)
export(teal_data_module)
export(teal_slices)
export(teal_transform_module)
export(ui_session_info)
export(ui_teal)
export(ui_teal_with_splash)
export(ui_transform_teal_data)
Expand Down
5 changes: 4 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@
* Possibility to download lockfile to restore app session for reproducibility. #479
* Datasets which name starts with `.` are ignored when `module`'s `datanames` is set as `"all"`.
* Added warning when reserved `datanames`, such as `all` and `.raw_data` are being used.
* Added `add_custom_server()` to allow adding custom server logic to the main shiny server function of a teal app.

### Breaking changes

* Setting `datanames()` on `data` passed to teal application no longer has effect. In order to change `teal_module`'s
`datanames` one should modify `module$datanames`.
* The `landing_popup_module()` needs to be passed as the `landing_popup` argument of `init` instead of being passed as a module of the `modules` argument of `init`.
* `landing_popup_module()` is deprecated. Please use `add_landing_popup()` function to add a landing popup for your teal application.
* `teal` no longer re-export `%>%`. Please load `library(magrittr)` instead or use `|>` from `base`.
* `build_app_title` will be removed in the future release. Please use the `modify_title()` function to change the title for your teal application.
* The `title`, `header`, and `footer` arguments of the `init()` function are deprecated. Please use the `modify_title`, `modify_header`, and `modify_footer` respectively.

### Enhancement

Expand Down
45 changes: 36 additions & 9 deletions R/TealAppDriver.R
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ TealAppDriver <- R6::R6Class( # nolint: object_name.
#' @description
#' Initialize a `TealAppDriver` object for testing a `teal` application.
#'
#' @param data,modules,filter,title,header,footer,landing_popup arguments passed to `init`
#' @param data,modules,filter arguments passed to `init`
#' @param title_args,header,footer,landing_popup_args to pass into the modifier functions.
#' @param timeout (`numeric`) Default number of milliseconds for any timeout or
#' timeout_ parameter in the `TealAppDriver` class.
#' Defaults to 20s.
Expand All @@ -45,25 +46,51 @@ TealAppDriver <- R6::R6Class( # nolint: object_name.
initialize = function(data,
modules,
filter = teal_slices(),
title = build_app_title(),
title_args = list(),
header = tags$p(),
footer = tags$p(),
landing_popup = NULL,
landing_popup_args = NULL,
timeout = rlang::missing_arg(),
load_timeout = rlang::missing_arg(),
...) {
private$data <- data
private$modules <- modules
private$filter <- filter

new_title <- modifyList(
list(
title = "Custom Teal App Title",
favicon = "https://raw.githubusercontent.com/insightsengineering/hex-stickers/main/PNG/teal.png"
vedhav marked this conversation as resolved.
Show resolved Hide resolved
),
title_args
)
app <- init(
data = data,
modules = modules,
filter = filter,
title = title,
header = header,
footer = footer,
landing_popup = landing_popup,
)
filter = filter
) |>
vedhav marked this conversation as resolved.
Show resolved Hide resolved
modify_title(title = new_title$title, favicon = new_title$favicon) |>
modify_header(header) |>
modify_footer(footer)

if (!is.null(landing_popup_args)) {
default_args <- list(
title = NULL,
content = NULL,
buttons = modalButton("Accept")
)
landing_popup_args[names(default_args)] <- Map(
function(x, y) if (is.null(y)) x else y,
default_args,
landing_popup_args[names(default_args)]
)
app <- add_landing_popup(
app,
title = landing_popup_args$title,
content = landing_popup_args$content,
buttons = landing_popup_args$button
)
}

# Default timeout is hardcoded to 4s in shinytest2:::resolve_timeout
# It must be set as parameter to the AppDriver
Expand Down
165 changes: 103 additions & 62 deletions R/init.R
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,25 @@
#' more details.
#' @param filter (`teal_slices`) Optionally,
#' specifies the initial filter using [teal_slices()].
#' @param title (`shiny.tag` or `character(1)`) Optionally,
#' @param title (`shiny.tag` or `character(1)`) `r lifecycle::badge("deprecated")` Optionally,
#' the browser window title. Defaults to a title "teal app" with the icon of NEST.
#' Can be created using the `build_app_title()` or
#' by passing a valid `shiny.tag` which is a head tag with title and link tag.
#' @param header (`shiny.tag` or `character(1)`) Optionally,
#' This parameter is deprecated. Use `modify_title()` on the teal app object instead.
#' @param header (`shiny.tag` or `character(1)`) `r lifecycle::badge("deprecated")` Optionally,
#' the header of the app.
#' @param footer (`shiny.tag` or `character(1)`) Optionally,
#' This parameter is deprecated. Use `modify_header()` on the teal app object instead.
#' @param footer (`shiny.tag` or `character(1)`) `r lifecycle::badge("deprecated")` Optionally,
#' the footer of the app.
#' This parameter is deprecated. Use `modify_footer()` on the teal app object instead.
#' @param id `r lifecycle::badge("deprecated")` (`character`) Optionally,
#' a string specifying the `shiny` module id in cases it is used as a `shiny` module
#' rather than a standalone `shiny` app. This is a legacy feature. Deprecated since v0.15.3
#' please use [ui_teal()] and [srv_teal()] instead.
#' @param id `r lifecycle::badge("deprecated")` (`character`) Optionally,
#' a string specifying the `shiny` module id in cases it is used as a `shiny` module
#' rather than a standalone `shiny` app. This is a legacy feature. Deprecated since v0.15.3
#' please use [ui_teal()] and [srv_teal()] instead.
#'
#' @param landing_popup (`teal_module_landing`) Optionally,
#' a `landing_popup_module` to show up as soon as the teal app is initialized.
#'
#' @return Named list containing server and UI functions.
#'
Expand Down Expand Up @@ -95,17 +99,15 @@
init <- function(data,
modules,
filter = teal_slices(),
title = build_app_title(),
header = tags$p(),
footer = tags$p(),
id = lifecycle::deprecated(),
landing_popup = NULL) {
title = lifecycle::deprecated(),
vedhav marked this conversation as resolved.
Show resolved Hide resolved
header = lifecycle::deprecated(),
footer = lifecycle::deprecated(),
id = lifecycle::deprecated()) {
logger::log_debug("init initializing teal app with: data ('{ class(data) }').")

# argument checking (independent)
## `data`
checkmate::assert_multi_class(data, c("teal_data", "teal_data_module"))
checkmate::assert_class(landing_popup, "teal_module_landing", null.ok = TRUE)

## `modules`
checkmate::assert(
Expand All @@ -123,44 +125,9 @@ init <- function(data,
## `filter`
checkmate::assert_class(filter, "teal_slices")

## all other arguments
checkmate::assert(
.var.name = "title",
checkmate::check_string(title),
checkmate::check_multi_class(title, c("shiny.tag", "shiny.tag.list", "html"))
)
checkmate::assert(
.var.name = "header",
checkmate::check_string(header),
checkmate::check_multi_class(header, c("shiny.tag", "shiny.tag.list", "html"))
)
checkmate::assert(
.var.name = "footer",
checkmate::check_string(footer),
checkmate::check_multi_class(footer, c("shiny.tag", "shiny.tag.list", "html"))
)
gogonzo marked this conversation as resolved.
Show resolved Hide resolved

# log
teal.logger::log_system_info()

# argument transformations
## `modules` - landing module
landing <- extract_module(modules, "teal_module_landing")
if (length(landing) == 1L) {
landing_popup <- landing[[1L]]
modules <- drop_module(modules, "teal_module_landing")
lifecycle::deprecate_soft(
when = "0.15.3",
what = "landing_popup_module()",
details = paste(
"Pass `landing_popup_module` to the `landing_popup` argument of the `init` ",
"instead of wrapping it into `modules()` and passing to the `modules` argument"
)
)
} else if (length(landing) > 1L) {
stop("Only one `landing_popup_module` can be used.")
}

## `filter` - set app_id attribute unless present (when restoring bookmark)
if (is.null(attr(filter, "app_id", exact = TRUE))) attr(filter, "app_id") <- create_app_id(data, modules)

Expand Down Expand Up @@ -222,6 +189,11 @@ init <- function(data,
)
}

# argument transformations
## `modules` - landing module
landing <- extract_module(modules, "teal_module_landing")
modules <- drop_module(modules, "teal_module_landing")


if (lifecycle::is_present(id)) {
lifecycle::deprecate_soft(
Expand All @@ -237,25 +209,94 @@ init <- function(data,
id <- character(0)
}
ns <- NS(id)

# Note: UI must be a function to support bookmarking.
res <- list(
ui = function(request) {
ui_teal(
id = ns("teal"),
modules = modules,
title = title,
header = header,
footer = footer
)
},
server = function(input, output, session) {
if (!is.null(landing_popup)) {
do.call(landing_popup$server, c(list(id = "landing_module_shiny_id"), landing_popup$server_args))
res <- structure(
list(
ui = function(request) {
fluidPage(
title = tags$div(
id = "teal-app-title",
tags$head(
tags$title("teal app"),
tags$link(
rel = "icon",
href = "https://raw.githubusercontent.com/insightsengineering/hex-stickers/main/PNG/nest.png",
Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure

sizes = "any"
)
)
),
tags$header(
id = "teal-header",
tags$div(id = "teal-header-content")
),
ui_teal(
id = "teal",
modules = modules
),
tags$footer(
id = "teal-footer",
tags$div(id = "teal-footer-content"),
ui_session_info("session_info")
vedhav marked this conversation as resolved.
Show resolved Hide resolved
)
)
},
server = function(input, output, session) {
srv_teal(id = "teal", data = data, modules = modules, filter = deep_copy_filter(filter))
srv_session_info("session_info")
vedhav marked this conversation as resolved.
Show resolved Hide resolved
}
srv_teal(id = ns("teal"), data = data, modules = modules, filter = deep_copy_filter(filter))
}
),
class = "teal_app"
)

if (lifecycle::is_present(title)) {
checkmate::assert_multi_class(title, c("shiny.tag", "shiny.tag.list", "html", "character"))
lifecycle::deprecate_warn(
vedhav marked this conversation as resolved.
Show resolved Hide resolved
when = "0.15.3",
vedhav marked this conversation as resolved.
Show resolved Hide resolved
what = "init(title)",
details = "Use `modify_title()` on the teal app object instead."
vedhav marked this conversation as resolved.
Show resolved Hide resolved
)
res <- modify_title(res, title)
}
if (lifecycle::is_present(header)) {
checkmate::assert_multi_class(header, c("shiny.tag", "shiny.tag.list", "html", "character"))
lifecycle::deprecate_warn(
when = "0.15.3",
what = "init(header)",
details = paste(
"Use `modify_header()` on the teal app object instead."
)
)
res <- modify_header(res, header)
}
if (lifecycle::is_present(footer)) {
checkmate::assert_multi_class(footer, c("shiny.tag", "shiny.tag.list", "html", "character"))
lifecycle::deprecate_warn(
when = "0.15.3",
what = "init(footer)",
details = paste(
"Use `modify_footer()` on the teal app object instead."
)
)
res <- modify_footer(res, footer)
}

if (length(landing) == 1L) {
res <- teal_extend_server(res, function(input, output, session) {
do.call(landing[[1L]]$server, c(list(id = "landing_module_shiny_id")))
})
lifecycle::deprecate_warn(
when = "0.15.3",
what = "landing_popup_module()",
details = paste(
"landing_popup_module() is deprecated.",
"Use add_landing_popup() on the teal app object instead."
)
)
} else if (length(landing) > 1L) {
stop("Only one `landing_popup_module` can be used.")
}

logger::log_debug("init teal app has been initialized.")

res
Expand Down
Loading
Loading