Skip to content

Redesign the teal modules #1548

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

Open
wants to merge 29 commits into
base: main
Choose a base branch
from
Open

Redesign the teal modules #1548

wants to merge 29 commits into from

Conversation

vedhav
Copy link
Contributor

@vedhav vedhav commented Jun 12, 2025

Closes #1525 and potentially address #1539

@vedhav vedhav added enhancement New feature or request core labels Jun 12, 2025
@gogonzo gogonzo self-assigned this Jun 12, 2025
@vedhav vedhav requested review from gogonzo and removed request for gogonzo June 20, 2025 06:38
@vedhav
Copy link
Contributor Author

vedhav commented Jun 23, 2025

There's a new widget for a sidebar overlay .sidebar_overlay() that can being the UI from left/right side of the page. I was thinking we can bring the teal_data_module ui from the left side and the report previewer ui from the right side. This PR will only implement the former and we can implement report previewer after it is merged. I also noticed there was still some unused CSS/JS code so removed them.

Examples for testing
devtools::load_all("../teal")

modules <- modules(
  example_module("One"),
  example_module("Two"),
  example_module("Three"),
  modules(
    label = "Nest level 1",
    example_module("Double Nested one"),
    modules(
      label = "Nest level 2",
      example_module("Inception one"),
      example_module("Inception two")
    )
  ),
  example_module("Module with a long name"),
  teal.modules.general::tm_variable_browser("Variable Browser"),
  modules(
    label = "Nested",
    example_module("Nested one"),
    example_module("Nested two")
  )
)

tdm_auto_resolve_once <- teal_data_module(
  ui = function(id) {
    fluidPage(
      numericInput(NS(id, "iris_rows"), "iris rows", min = 0, max = 150, step = 1, value = 10),
      actionButton(NS(id, "submit"), "Submit")
    )
  },
  server = function(id, ...) {
    moduleServer(id, function(input, output, session) {
      reactive(
        teal_data(iris = head(iris, input$iris_rows), mtcars = mtcars)
      )
    })
  },
  once = TRUE
)

tdm_auto_resolve_not_once <- teal_data_module(
  ui = function(id) {
    fluidPage(
      numericInput(NS(id, "iris_rows"), "iris rows", min = 0, max = 150, step = 1, value = 10)
    )
  },
  server = function(id, ...) {
    moduleServer(id, function(input, output, session) {
      reactive(
        teal_data(iris = head(iris, input$iris_rows), mtcars = mtcars)
      )
    })
  },
  once = FALSE
)

tdm_manual_resolve_once <- teal_data_module(
  ui = function(id) {
    fluidPage(
      numericInput(NS(id, "iris_rows"), "iris rows", min = 0, max = 150, step = 1, value = 10),
      actionButton(NS(id, "submit"), "Submit")
    )
  },
  server = function(id, ...) {
    moduleServer(id, function(input, output, session) {
      eventReactive(input$submit, {
        teal_data(iris = head(iris, input$iris_rows), mtcars = mtcars)
      })
    })
  },
  once = TRUE
)

tdm_manual_resolve_not_once <- teal_data_module(
  ui = function(id) {
    fluidPage(
      numericInput(NS(id, "iris_rows"), "iris rows", min = 0, max = 150, step = 1, value = 10),
      actionButton(NS(id, "submit"), "Submit")
    )
  },
  server = function(id, ...) {
    moduleServer(id, function(input, output, session) {
      eventReactive(input$submit, {
        teal_data(iris = head(iris, input$iris_rows), mtcars = mtcars)
      })
    })
  },
  once = FALSE
)

td_simple <- teal_data(iris = iris, mtcars = mtcars)

app <- init(
  # data = tdm_auto_resolve_once,
  data = tdm_auto_resolve_not_once,
  # data = tdm_manual_resolve_once,
  # data = tdm_manual_resolve_not_once,
  # data = td_simple,
  modules = modules
)

shinyApp(app$ui, app$server, enableBookmarking = "server")

@vedhav vedhav marked this pull request as ready for review June 24, 2025 08:48
@vedhav vedhav requested a review from gogonzo June 24, 2025 08:48
@vedhav
Copy link
Contributor Author

vedhav commented Jun 24, 2025

Apart from documentation other things are ready for review @gogonzo

Copy link
Contributor

github-actions bot commented Jun 24, 2025

badge

Code Coverage Summary

Filename                          Stmts    Miss  Cover    Missing
------------------------------  -------  ------  -------  ---------------------------------------------------------------------------------------------------------------------------------
R/checkmate.R                        24       0  100.00%
R/dummy_functions.R                  67       2  97.01%   46, 48
R/include_css_js.R                   11       0  100.00%
R/init.R                            142      96  32.39%   137-158, 188-196, 206-231, 234-235, 242-251, 254-263, 266-275, 279-289, 291
R/landing_popup_module.R             34      34  0.00%    22-57
R/module_bookmark_manager.R         161     125  22.36%   55-68, 88-142, 147-148, 160, 207, 242-319
R/module_data_summary.R             177       8  95.48%   40, 50, 205, 236-240
R/module_filter_data.R               64       0  100.00%
R/module_filter_manager.R           230      50  78.26%   73-82, 90-95, 108-112, 117-118, 291-314, 340, 367, 379, 386-387
R/module_init_data.R                 74       6  91.89%   38-43
R/module_session_info.R              18       7  61.11%   35-41
R/module_snapshot_manager.R         216     139  35.65%   104-113, 121-133, 152-153, 170-180, 184-199, 201-208, 215-230, 234-238, 240-246, 249-262, 265-273, 303-317, 320-331, 334-340, 354
R/module_teal_data.R                149      76  48.99%   43-149
R/module_teal_lockfile.R            131      69  47.33%   33-37, 45-57, 60-62, 76, 86-88, 92-96, 100-102, 110-119, 122, 124, 126-127, 142-146, 161-162, 177-186, 196-201
R/module_teal_navigation.R          373      24  93.57%   45, 213, 239-241, 348-351, 355-358, 362-365, 414, 471, 544-548
R/module_teal_with_splash.R          33      33  0.00%    24-61
R/module_teal.R                     167      26  84.43%   50-54, 73, 119-120, 163, 184-200, 202
R/module_transform_data.R           116       5  95.69%   130-134
R/modules.R                         317      59  81.39%   174-178, 233-236, 360-380, 388, 394, 571-577, 590-598, 613-628, 674, 687, 759, 773, 781-783, 793
R/reporter_previewer_module.R        19       0  100.00%
R/show_rcode_modal.R                 23      23  0.00%    17-41
R/tdata.R                            14      14  0.00%    19-61
R/teal_data_module-eval_code.R       24       0  100.00%
R/teal_data_module-within.R           7       0  100.00%
R/teal_data_module.R                 20       0  100.00%
R/teal_data_utils.R                  10       0  100.00%
R/teal_modifiers.R                   71      71  0.00%    26-214
R/teal_reporter.R                    70       8  88.57%   69, 77-82, 131-132, 135, 152
R/teal_slices-store.R                29       0  100.00%
R/teal_slices.R                      63       0  100.00%
R/teal_transform_module.R            45       0  100.00%
R/TealAppDriver.R                   385     385  0.00%    57-776
R/utils.R                           250      38  84.80%   400-449
R/validate_inputs.R                  32       0  100.00%
R/validations.R                      58      37  36.21%   118-406
R/zzz.R                              15      11  26.67%   4-18
TOTAL                              3639    1346  63.01%

Diff against main

Filename                         Stmts    Miss  Cover
-----------------------------  -------  ------  -------
R/dummy_functions.R                  0      -9  +13.43%
R/include_css_js.R                 -11     -17  +77.27%
R/module_bookmark_manager.R          0      -5  +3.11%
R/module_data_summary.R              0      -2  +1.13%
R/module_filter_data.R               0      -2  +3.12%
R/module_filter_manager.R            0      -7  +3.04%
R/module_init_data.R                 0      +6  -8.11%
R/module_snapshot_manager.R          0      -7  +3.24%
R/module_teal_lockfile.R             0     +14  -10.69%
R/module_teal_navigation.R        +373     +24  +93.57%
R/module_teal.R                    +14     -25  +17.76%
R/module_transform_data.R            0      -2  +1.72%
R/modules.R                        +32      +6  -0.02%
R/reporter_previewer_module.R        0      -1  +5.26%
TOTAL                             +408     -27  +6.51%

Results for commit: 5ac435b

Minimum allowed coverage is 80%

♻️ This comment has been updated with latest results

Copy link
Contributor

github-actions bot commented Jun 24, 2025

Unit Tests Summary

  1 files   26 suites   2m 7s ⏱️
267 tests 221 ✅ 46 💤 0 ❌
460 runs  414 ✅ 46 💤 0 ❌

Results for commit 5ac435b.

♻️ This comment has been updated with latest results.

Copy link
Contributor

github-actions bot commented Jun 24, 2025

Unit Test Performance Difference

Test Suite $Status$ Time on main $±Time$ $±Tests$ $±Skipped$ $±Failures$ $±Errors$
module_teal 💚 $165.33$ $-58.40$ $0$ $0$ $0$ $0$
Additional test case details
Test Suite $Status$ Time on main $±Time$ Test Case
module_teal 💚 $2.60$ $-1.10$ appends_added_duplicated_slice_and_makes_new_slice_id_unique
module_teal 💚 $4.62$ $-1.84$ appends_new_slice_and_activates_in_global_filters_when_added_in_a_module_if_module_specific
module_teal 💚 $3.84$ $-1.37$ appends_new_slice_and_activates_in_module_when_added_in_a_module_if_module_specific
module_teal 💚 $2.86$ $-1.21$ are_receiving_reactive_data_which_triggers_on_change
module_teal 💚 $3.10$ $-1.08$ change_in_the_slicesGlobal_causes_module_s_data_filtering
module_teal 💚 $3.66$ $-1.62$ clicking_reset_button_restores_initial_filters_state_when_module_specific
module_teal 💚 $5.30$ $-2.42$ clicking_reset_button_restores_initial_filters_with_respect_to_mapping_state_when_module_specific
module_teal 💚 $4.59$ $-2.05$ deactivates_in_global_filters_when_removed_from_module_if_module_specific
module_teal 💚 $3.99$ $-1.43$ deactivates_in_module_when_removed_from_module_if_module_specific
module_teal 💚 $3.34$ $-1.49$ displays_parent_s_Subjects_with_count_based_on_primary_key
module_teal 💚 $2.84$ $-1.28$ evaluates_custom_qenv_call_after_filter_is_applied
module_teal 💚 $2.64$ $-1.09$ pauses_when_transformator_throws_validation_error
module_teal 💚 $2.59$ $-1.22$ receives_all_possible_objects_while_those_not_specified_in_module_datanames_are_unfiltered
module_teal 💚 $4.98$ $-2.34$ sets_filters_from_mapping_global_filters_to_all_modules_FilteredData_when_module_specific
module_teal 💚 $4.80$ $-2.32$ sets_filters_from_mapping_mod_to_all_modules_FilteredData_when_module_specific
module_teal 💚 $3.73$ $-1.26$ sets_filters_from_mapping_mod_to_module_s_FilteredData_when_module_specific
module_teal 💚 $3.81$ $-1.34$ slices_in_slicesGlobal_and_in_FilteredData_refer_to_the_same_object
module_teal 💚 $7.70$ $-1.24$ summary_table_displays_MAE_dataset_added_in_transformators
modules 💀 $0.01$ $-0.01$ modules_depth_accepts_depth_as_integer
modules 💀 $0.01$ $-0.01$ modules_depth_accepts_modules_to_be_teal_module_or_teal_modules
modules 💀 $0.01$ $-0.01$ modules_depth_increases_depth_by_1_for_each_teal_modules
modules 💀 $0.00$ $-0.00$ modules_depth_returns_depth_0_by_default
modules 💀 $0.00$ $-0.00$ modules_depth_returns_depth_same_as_input_for_teal_module

Results for commit b34e6c4

♻️ This comment has been updated with latest results.

@vedhav vedhav force-pushed the 1525-redesign-modules@main branch from 95d18a5 to f57bd8a Compare June 26, 2025 11:37
@vedhav vedhav force-pushed the 1525-redesign-modules@main branch from a8bed55 to 953249c Compare June 26, 2025 12:01
Copy link
Contributor

@gogonzo gogonzo left a comment

Choose a reason for hiding this comment

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

I like this design better than sliding from the side.

R/module_teal.R Outdated
if (inherits(data, "teal_data_module")) {
teal_data_resolved_state <- reactiveVal(FALSE)
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is it needed? When data_signatured returns teal_data then it is resolved, we don't need a new object to determine this. If data_signatured() returns req-error, observeEvent shouldn't be triggered.

Suggested change
teal_data_resolved_state <- reactiveVal(FALSE)

@@ -165,8 +152,10 @@ srv_teal <- function(id, data, modules, filter = teal_slices()) {

data_load_status <- reactive({
if (inherits(data_handled(), "teal_data")) {
teal_data_resolved_state(TRUE)
Copy link
Contributor

Choose a reason for hiding this comment

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

Doesn't seem to be needed as data_load_status holds the same information

Suggested change
teal_data_resolved_state(TRUE)

R/module_teal.R Outdated
Comment on lines 173 to 175
observeEvent(teal_data_resolved_state(), {
if (teal_data_resolved_state()) {
shinyjs::enable(id = "close_teal_data_module_modal")
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
observeEvent(teal_data_resolved_state(), {
if (teal_data_resolved_state()) {
shinyjs::enable(id = "close_teal_data_module_modal")
observeEvent(data_load_status(), {
if (identical(data_load_status(), "ok")) {
shinyjs::enable(id = "close_teal_data_module_modal")

R/module_teal.R Outdated
Comment on lines 183 to 187
observeEvent(data_handled(), {
if (inherits(data_handled(), "teal_data")) {
shinyjs::enable(id = "close_teal_data_module_modal")
}
})
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
observeEvent(data_handled(), {
if (inherits(data_handled(), "teal_data")) {
shinyjs::enable(id = "close_teal_data_module_modal")
}
})
observeEvent(data_load_status(), {
if (identical(data_load_status(), "ok")) {
shinyjs::enable(id = "close_teal_data_module_modal")
}
})

Copy link
Contributor

Choose a reason for hiding this comment

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

or use data_signatured(). Please have a look at srv_teal to see if data_load_status is used consistently.

// not included in the original HTML

// this code alows the show R code "copy to clipbaord" button to work
var clipboard = new ClipboardJS(".btn[data-clipboard-target]");
Copy link
Contributor

Choose a reason for hiding this comment

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

Just saying that show_rcode_modal uses this. It is still soft (not hard) deprecated

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍🏽 Let me move this dependency to just the show_rcode_modal() for now.

@@ -118,8 +73,40 @@ srv_teal <- function(id, data, modules, filter = teal_slices()) {
shinyjs::showLog()
}

# `JavaScript` code
run_js_files(files = "init.js")
output$main_teal_ui <- renderUI({
Copy link
Contributor

Choose a reason for hiding this comment

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

Given that data module is a modal it is not needed so much to keep it in the server. IMO this can be moved to the UI

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
core enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Feature Request]: Implement teal module design
2 participants