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

1304 handover error@main #1341

Merged
merged 110 commits into from
Oct 3, 2024
Merged

1304 handover error@main #1341

merged 110 commits into from
Oct 3, 2024

Conversation

gogonzo
Copy link
Contributor

@gogonzo gogonzo commented Sep 4, 2024

Alternative solution to #1330. Closes #1304, #1307, and #1308

  1. When teal_data_module fails, then teal-module-tabs are disabled. When teal_data_module returns teal_data again teal-module-tabs are enabled
  2. When reactive data passed directly to srv_teal fails, then the whole tab-panel is hidden and error message is shown. Warning messages are displayed over tab-panel.
  3. when teal_transform_module fails then following teal_transform_module(s) show generic message that something was wrong. Reason for this is the same as (3).
  4. when teal_transform_module fails then teal-module output is disabled and generic failure message is shown in the main panel. We decided to show a generic failure message as "real failure message" should be only shown in the place where error occurred to no cause confusion.
  5. failing teal_data_module/teal_transform_module fallbacks to previous valid data (see exaplanation below)

The most important part of the implementation is that when teal_data_module fails then it return the previous valid data (i.e. it return unchanged data). This means that failure doesn't trigger downstream reactivity and we don't need to deal with data input as error. In other words, this implementation halts reactivity when something goes wrong.
When something goes wrong, teal-module-output is hidden and instead error message is displayed.

Also, I've moved data completely away from ui and now if there is teal_data_module then data-tab is added dynamically.

app w/ teal_data_module
options(
  teal.log_level = "TRACE",
  teal.show_js_log = TRUE,
  # teal.bs_theme = bslib::bs_theme(version = 5),
  shiny.bookmarkStore = "server"
)

# pkgload::load_all("teal.data")
pkgload::load_all("teal")

make_data <- function(datanames = c("ADSL", "ADTTE")) {
  data_obj <- teal.data::teal_data()
  if ("ADSL" %in% datanames) {
    data_obj <- within(data_obj, ADSL <- teal.data::rADSL)
  }
  if ("ADTTE" %in% datanames) {
    data_obj <- within(data_obj, ADTTE <- teal.data::rADTTE)
  }
  join_keys(data_obj) <- default_cdisc_join_keys[datanames]
  teal.data::datanames(data_obj) <- datanames
  data_obj
}

trans <- list(
  teal_transform_module(
    ui = function(id) {
      ns <- NS(id)
      tagList(
        selectizeInput(
          ns("errortype"),
          label = "Error Type",
          choices = c(
            "ok", "insufficient datasets", "no data",
            "qenv.error", "error in reactive", "validate error", "silent.shiny.error", "not a reactive"
          )
        )
      )
    },
    server = function(id, data) {
      moduleServer(id, function(input, output, session) {
        logger::log_trace("example_module_transform2 initializing.")
        reactive({
          switch(input$errortype,
            ok = data(),
            `insufficient datasets` = teal:::.subset_teal_data(data(), "ADSL"),
            `no data` = teal_data(),
            qenv.error = within(teal_data(), stop("\nthis is qenv.error in teal_transform_module\n")),
            `error in reactive` = stop("\nerror in a reactive in teal_transform_module\n"),
            `validate error` = validate(need(FALSE, "\nvalidate error in teal_transform_module\n")),
            `silent.shiny.error` = req(FALSE)
          )
        })
      })
    }
  )
)

data <- teal_data_module(
  once = FALSE,
  ui = function(id) {
    ns <- NS(id)
    tagList(
      selectizeInput(
        ns("errortype"),
        label = "Error Type",
        choices = c(
          "ok", "insufficient datasets", "no data",
          "qenv.error", "error in reactive", "validate error", "silent.shiny.error", "not a reactive"
        )
      ),
      actionButton(ns("submit"), "Go!")
    )
  },
  server = function(id, ...) {
    moduleServer(id, function(input, output, session) {
      logger::log_trace("example_module_transform2 initializing.")
      eventReactive(input$submit, {
        switch(input$errortype,
          ok = make_data(),
          `insufficient datasets` = make_data(datanames = "ADSL"),
          `no data` = teal_data(),
          qenv.error = within(data(), stop("\nthis is qenv.error in teal_data_module\n")),
          `error in reactive` = stop("\nerror in a reactive in teal_data_module\n"),
          `validate error` = validate(need(FALSE, "\nvalidate error in teal_data_module\n")),
          `silent.shiny.error` = req(FALSE)
        )
      })
    })
  }
)

app <- teal::init(
  data = data,
  modules = list(
    example_module("mod-1", transformers = c(trans, trans, trans), datanames = c("ADSL", "ADTTE")),
    example_module("mod-2", transformers = trans, datanames = c("ADSL", "ADTTE")),
    module(
      label = "I was made to annoy you",
      ui = function(id) NULL,
      server = function(id, data) {
        moduleServer(id, function(input, output, session) {
          observe({
            teal.data::datanames(data())
            ADSL <- data()[["ADSL"]]
            ADSL$AGE
          })

          observeEvent(data(), {
            print(data()[["ADSL"]]$SEX)
          })
        })
      },
      datanames = "ADSL"
    )
  ),
  filter = teal_slices(
    teal_slice("ADSL", "SEX"),
    teal_slice("ADSL", "AGE", selected = c(18L, 65L)),
    teal_slice("ADTTE", "PARAMCD", selected = "CRSD"),
    include_varnames = list(
      ADSL = c("SEX", "AGE")
    )
  )
)

runApp(app)
app wrapped
options(
  teal.log_level = "TRACE",
  teal.show_js_log = TRUE,
  # teal.bs_theme = bslib::bs_theme(version = 5),
  shiny.bookmarkStore = "server"
)
library(scda)
pkgload::load_all("teal")

make_data <- function(datanames = c("ADSL", "ADTTE")) {
  data_obj <- teal.data::teal_data()
  if ("ADSL" %in% datanames) {
    data_obj <- within(data_obj, ADSL <- teal.data::rADSL)
  }
  if ("ADTTE" %in% datanames) {
    data_obj <- within(data_obj, ADTTE <- teal.data::rADTTE)
  }
  join_keys(data_obj) <- default_cdisc_join_keys[datanames]
  teal.data::datanames(data_obj) <- datanames
  data_obj
}

ui_data <- function(id) {
  ns <- NS(id)
  tagList(
    selectizeInput(
      ns("errortype"),
      label = "Error Type",
      choices = c(
        "ok", "insufficient datasets", "no data",
        "qenv.error", "error in reactive", "validate error", "silent.shiny.error", "not a reactive"
      )
    ),
    actionButton(ns("submit"), "Go!")
  )
}

srv_data <- function(id, ...) {
  moduleServer(id, function(input, output, session) {
    logger::log_trace("example_module_transform2 initializing.")
    eventReactive(input$submit, {
      switch(input$errortype,
        ok = make_data(),
        `insufficient datasets` = make_data(datanames = "ADSL"),
        `no data` = teal_data(),
        qenv.error = within(data(), stop("\nthis is qenv.error in teal_data_module\n")),
        `error in reactive` = stop("\nerror in a reactive in teal_data_module\n"),
        `validate error` = validate(need(FALSE, "\nvalidate error in teal_data_module\n")),
        `silent.shiny.error` = req(FALSE)
      )
    })
  })
}

modules <- modules(
  teal.modules.general::tm_data_table("Data Table"),
  example_module("Example Module", datanames = "ADTTE"),
  module(
    ui = function(id) {
      ns <- NS(id)
      tagList(
        tableOutput(ns("filter_summary"))
      )
    },
    server = function(id, datasets) {
      moduleServer(id, function(input, output, session) {
        output$filter_summary <- renderTable({
          datasets$get_filter_overview(datanames = datasets$datanames())
        })
      })
    }
  )
)

shinyApp(
  ui = function(request) {
    fluidPage(
      ui_data("data"),
      ui_teal(id = "teal", modules = modules)
    )
  },
  server = function(input, output, session) {
    data_rv <- srv_data("data", data = data, modules = modules)
    srv_teal(id = "teal", data = data_rv, modules = modules)
  }
)

vedhav and others added 26 commits August 28, 2024 08:53
Signed-off-by: Vedha Viyash <[email protected]>
Co-authored-by: Marcin <[email protected]>
Signed-off-by: Vedha Viyash <[email protected]>
Co-authored-by: Marcin <[email protected]>
Signed-off-by: Vedha Viyash <[email protected]>
Co-authored-by: Marcin <[email protected]>
Signed-off-by: Vedha Viyash <[email protected]>
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>
@gogonzo gogonzo changed the base branch from main to 1304-handle-data-inputs@main September 4, 2024 08:56
Copy link
Contributor

github-actions bot commented Sep 4, 2024

Unit Tests Summary

  1 files   25 suites   8m 33s ⏱️
253 tests 249 ✅ 4 💤 0 ❌
508 runs  504 ✅ 4 💤 0 ❌

Results for commit 9c1b9d6.

♻️ This comment has been updated with latest results.

Copy link
Contributor

github-actions bot commented Sep 4, 2024

Unit Test Performance Difference

Test Suite $Status$ Time on main $±Time$ $±Tests$ $±Skipped$ $±Failures$ $±Errors$
module_teal 💔 $60.16$ $+2.70$ $-1$ $-2$ $0$ $0$
shinytest2-landing_popup 💔 $43.56$ $+1.83$ $0$ $0$ $0$ $0$
shinytest2-module_bookmark_manager 💔 $34.66$ $+1.59$ $0$ $0$ $0$ $0$
shinytest2-reporter 💚 $70.42$ $-2.38$ $0$ $0$ $0$ $0$
shinytest2-teal_data_module 💚 $53.17$ $-5.04$ $0$ $0$ $0$ $0$
shinytest2-teal_slices 💚 $62.25$ $-1.06$ $0$ $0$ $0$ $0$
Additional test case details
Test Suite $Status$ Time on main $±Time$ Test Case
module_teal 👶 $+0.22$ are_not_called_when_teal_data_module_returns_qenv.error
module_teal 👶 $+0.21$ are_not_called_when_teal_data_module_returns_validation_error
module_teal 👶 $+0.26$ are_not_called_when_teal_data_module_throws_an_error
module_teal 💀 $0.17$ $-0.17$ are_not_called_when_the_teal_data_module_returns_qenv.error
module_teal 💀 $0.17$ $-0.17$ are_not_called_when_the_teal_data_module_returns_validation_error
module_teal 💀 $0.19$ $-0.19$ are_not_called_when_the_teal_data_module_throw_en_error
module_teal 💀 $0.01$ $-0.01$ continues_when_transformer_throws_qenv_error_and_returns_unchanged_data
module_teal 💀 $0.59$ $-0.59$ continues_when_transformer_throws_validation_error_and_returns_unchanged_data
module_teal 👶 $+0.34$ pauses_when_transformer_throws_qenv_error
module_teal 👶 $+0.66$ pauses_when_transformer_throws_validation_error
module_teal 💀 $0.47$ $-0.47$ upstream_data_change_is_updated_on_transformer_fallback
module_teal 💀 $0.48$ $-0.48$ upstream_data_change_with_double_reactivity_resolves_with_correct_this_that
shinytest2-filter_panel 💀 $10.10$ $-10.10$ e2e_module_content_is_updated_when_a_data_is_filtered_in_filter_panel
shinytest2-filter_panel 👶 $+10.15$ e2e_module_content_is_updated_when_data_is_filtered_in_filter_panel
shinytest2-reporter 💚 $20.97$ $-1.94$ e2e_reporter_does_not_show_the_secondary_column_that_shows_filter_panel
shinytest2-reporter 💚 $14.50$ $-1.08$ e2e_reporter_previewer_module_do_not_show_data_summary_nor_filter_panel
shinytest2-teal_data_module 💚 $10.76$ $-2.40$ e2e_teal_data_module_gets_removed_after_successful_data_load_when_once_TRUE
shinytest2-teal_data_module 💚 $13.18$ $-1.31$ e2e_teal_data_module_inputs_change_teal_data_object_that_is_passed_to_teal_main_UI
shinytest2-teal_data_module 💚 $10.80$ $-1.93$ e2e_teal_data_module_will_have_a_delayed_load_of_datasets

Results for commit fe50356

♻️ This comment has been updated with latest results.

@gogonzo
Copy link
Contributor Author

gogonzo commented Sep 18, 2024

Hey, just checked the current state of the PR and I don't see a warning for no data nor insufficient datanames, only

I can see the warnings. Did you click the button?

"Some filters were not applied because of incompatibility with data. Contact app developer."
for cases where data is selected of that type, or a transformer is selected of that type. Is that intended?

Please clarify, I don't understand.

R/module_nested_tabs.R Outdated Show resolved Hide resolved
R/module_teal.R Outdated Show resolved Hide resolved
R/module_teal.R Outdated Show resolved Hide resolved
@m7pr
Copy link
Contributor

m7pr commented Sep 18, 2024

Hey, just checked the current state of the PR and I don't see a warning for no data nor insufficient datanames, only

I can see the warnings. Did you click the button?

I did : P I don't see them

"Some filters were not applied because of incompatibility with data. Contact app developer."
for cases where data is selected of that type, or a transformer is selected of that type. Is that intended?

Please clarify, I don't understand.

I only see a notification in the bottom right corner, but not a warning on the top left part of the app (in case of teal_data_module) and no warning inside transformer UI (in case for teal_transform_module).

@gogonzo
Copy link
Contributor Author

gogonzo commented Sep 18, 2024

I only see a notification in the bottom right corner, but not a warning on the top left part of the app (in case of teal_data_module) and no warning inside transformer UI (in case for teal_transform_module).

This is a warning for filters which are not applied (teal_slice for datasets which don't exist). Errors on top are related to the modules$datanames.

@gogonzo gogonzo assigned gogonzo and unassigned gogonzo Sep 27, 2024
@gogonzo gogonzo enabled auto-merge (squash) September 27, 2024 10:36
@gogonzo gogonzo disabled auto-merge September 30, 2024 06:36
@gogonzo gogonzo enabled auto-merge (squash) September 30, 2024 06:39
@gogonzo gogonzo disabled auto-merge September 30, 2024 06:43
Copy link
Contributor

@vedhav vedhav left a comment

Choose a reason for hiding this comment

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

Great work 💪🏽 The error handling is robust and I really like the clear distinction between the init data and data during transform.
The data_load_status for init data and is_transformer_failed for data transforms a good way to manage what is happening.
The show/disable/hide logic living inside nested tabs makes sense 👍🏽

I just have minor comments and we can merge this.

R/module_teal.R Outdated Show resolved Hide resolved
R/module_teal.R Outdated Show resolved Hide resolved
R/module_teal_data.R Outdated Show resolved Hide resolved
R/module_teal_data.R Outdated Show resolved Hide resolved
Copy link
Contributor

@vedhav vedhav left a comment

Choose a reason for hiding this comment

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

Works like a charm 🎉

@vedhav vedhav merged commit 7683b6f into main Oct 3, 2024
28 checks passed
@vedhav vedhav deleted the 1304-handover-error@main branch October 3, 2024 07:28
@github-actions github-actions bot locked and limited conversation to collaborators Oct 3, 2024
@m7pr
Copy link
Contributor

m7pr commented Oct 3, 2024

🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥 🔥

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
3 participants