-
-
Notifications
You must be signed in to change notification settings - Fork 46
{teal}
module returns a teal_report
object that extends from teal_data
#1541
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
base: main
Are you sure you want to change the base?
Changes from all commits
96e3945
7f56567
20bb0f0
2c36c7b
45d0f1e
52b7fc7
85622df
4881050
8a12408
910c26d
3279b6e
e7346fd
a616392
0716caf
813d5b5
e705f36
21e3955
486b565
3a1b5d6
36c2561
2d5d3a6
fe0545e
333a87c
86391e4
454d49e
620e5ba
17f5a4a
df3a62a
9f91260
2bf6481
06f2898
59b3a15
c2388eb
466f0e7
9990dca
c3538e5
c5301ff
ec60f50
eb9abf3
72456fc
366def0
35d4101
2667426
8729daa
7a5e099
0022f0d
c0b9836
795a246
30118ec
5829d61
4daffe4
ec5141a
ea2c7e5
2fad140
a8201af
0201c7a
4bf6e99
6cf260d
8be8963
ef03a5b
4ae9720
35d3ae2
0396d61
ab96d22
0372479
18b524e
6c92309
d1360e5
93cd49c
a47a24a
a6d3a8c
0857eb2
8330ddb
e90a5d5
835cf0f
05c2255
a803de7
bacf4cc
21e400a
6c62626
40d5147
daa23ad
693c8e5
9f6965a
3ca11ab
45da1b4
bcab748
8a1e9d3
a19a367
78ad8b2
b7cba1a
329f728
a66fa15
a31fdaa
860edf1
9047461
7c3b571
a7f76e9
33c0ff3
f01ad09
8b48ac0
1516f8f
8b37b72
d356591
473b987
8d2477e
60d5707
82fd605
f4ac12f
4f2e06a
65e6e04
93071a3
abb2307
290cbb9
cf9c3b4
52e71b1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,91 @@ | ||||||
#' Executes modifications to the result of a module | ||||||
#' | ||||||
#' Primarily used to modify the output object of module to change the containing | ||||||
#' report. | ||||||
#' @param x (`teal_data`) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
#' @param ui (`function(id, elem, ...)`) function to receive output (`shiny.tag`) from `x$ui` | ||||||
#' @param server (`function(input, output, session, data, ...)`) function to receive output data from `x$server` | ||||||
#' @param ... additional argument passed to `ui` and `server` by matching their formals names. | ||||||
#' @return A `teal_report` object with the result of the server function. | ||||||
#' @export | ||||||
after <- function(x, | ||||||
ui = function(id, elem) elem, | ||||||
server = function(input, output, session, data) data, | ||||||
...) { | ||||||
Comment on lines
+5
to
+14
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since
I think
should be updated to
and
to
? |
||||||
# todo: make a method for teal_app and remove teal_extend_server? | ||||||
checkmate::assert_multi_class(x, "teal_module") | ||||||
if (!is.function(ui) || !all(names(formals(ui)) %in% c("id", "elem"))) { | ||||||
stop("ui should be a function of id and elem") | ||||||
} | ||||||
if (!is.function(server) || !all(names(formals(server)) %in% c("input", "output", "session", "data"))) { | ||||||
stop("server should be a function of `input` and `output`, `session`, `data`") | ||||||
} | ||||||
Comment on lines
+20
to
+22
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are those checks even working if we pass server function without <teal_module> |> after(
server = function(data) {
teal.reporter::teal_card(data) <- c(
teal.reporter::teal_card(data),
"# added content",
"This content has been added through `after`"
)
data
}
) |
||||||
|
||||||
additional_args <- list(...) | ||||||
new_x <- x # because overwriting x$ui/server will cause infinite recursion | ||||||
new_x$ui <- .after_ui(x$ui, ui, additional_args) | ||||||
new_x$server <- .after_server(x$server, server, additional_args) | ||||||
new_x | ||||||
} | ||||||
|
||||||
.after_ui <- function(x, y, additional_args) { | ||||||
# add `_`-prefix to make sure objects are not masked in the wrapper functions | ||||||
`_x` <- x # nolint: object_name. | ||||||
`_y` <- y # nolint: object_name. | ||||||
new_x <- function(id, ...) { | ||||||
original_args <- as.list(environment()) | ||||||
if ("..." %in% names(formals(`_x`))) { | ||||||
original_args <- c(original_args, list(...)) | ||||||
} | ||||||
ns <- NS(id) | ||||||
original_args$id <- ns("wrapped") | ||||||
original_out <- do.call(`_x`, original_args, quote = TRUE) | ||||||
|
||||||
wrapper_args <- c( | ||||||
additional_args, | ||||||
list(id = ns("wrapper"), elem = original_out) | ||||||
) | ||||||
do.call(`_y`, args = wrapper_args[names(formals(`_y`))]) | ||||||
} | ||||||
formals(new_x) <- formals(x) | ||||||
new_x | ||||||
} | ||||||
|
||||||
.after_server <- function(x, y, additional_args) { | ||||||
# add `_`-prefix to make sure objects are not masked in the wrapper functions | ||||||
`_x` <- x # nolint: object_name. | ||||||
`_y` <- y # nolint: object_name. | ||||||
new_x <- function(id, ...) { | ||||||
original_args <- as.list(environment()) | ||||||
original_args$id <- "wrapped" | ||||||
if ("..." %in% names(formals(`_x`))) { | ||||||
original_args <- c(original_args, list(...)) | ||||||
} | ||||||
moduleServer(id, function(input, output, session) { | ||||||
original_out <- if (all(c("input", "output", "session") %in% names(formals(`_x`)))) { | ||||||
original_args$module <- `_x` | ||||||
do.call(shiny::callModule, args = original_args) | ||||||
} else { | ||||||
do.call(`_x`, original_args) | ||||||
} | ||||||
original_out_r <- reactive( | ||||||
if (is.reactive(original_out)) { | ||||||
original_out() | ||||||
} else { | ||||||
original_out | ||||||
} | ||||||
) | ||||||
wrapper_args <- utils::modifyList( | ||||||
additional_args, | ||||||
list(id = "wrapper", input = input, output = output, session = session) | ||||||
) | ||||||
reactive({ | ||||||
req(original_out_r()) | ||||||
wrapper_args$data <- original_out() | ||||||
do.call(`_y`, wrapper_args[names(formals(`_y`))], quote = TRUE) | ||||||
}) | ||||||
}) | ||||||
} | ||||||
formals(new_x) <- formals(x) | ||||||
new_x | ||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that this is a really bad name that can mean anything. It feels very much async related. Please reassess the name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to let you know @pawelru - this is a function that edits/manipulates
teal_data
(now extended toteal_report
class) after it was returned by module'sserver
. It is applied on a module level.So basically it is:
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about
modify_teal_module
oredit_teal_module
?Then, we'll have
.modify/edit_teal_module_ui
and.modify/edit_teal_module_srv
EDIT: I saw the comment that this was previously called
modify_reactive_output
.