insightsengineering / teal

Exploratory Web Apps for Analyzing Clinical Trial Data
https://insightsengineering.github.io/teal/
Other
168 stars 33 forks source link

Refactor nested_tabs module #534

Open gogonzo opened 2 years ago

gogonzo commented 2 years ago

Nested tabs is a violation of UI good practices. See the opinions on ui-stackoverflow (shared by @nikolas-burkoff ): https://ux.stackexchange.com/questions/104804/are-nested-tabs-in-desktop-view-good-to-use
https://ux.stackexchange.com/questions/5136/is-there-evidence-to-suggest-that-designing-tabs-within-tabs-creates-a-bad-user

Polkas commented 2 years ago

only research + issues at the end. A few meetings and voting for other devs.

gogonzo commented 1 year ago

From @nikolas-burkoff original comment here

We should also use a navbar page with menus to define the UI so this: image

navbarPage(
"NEST APP",
tabPanel("DDL"),
tabPanel("One module"),
navbarMenu(
"Nested modules",
tabPanel("Output 1"),
tabPanel("Output 2")
),
tabPanel("Another module"),
navbarMenu(
"Nested modules 2",
tabPanel("Output 3"),
tabPanel("Output 4")
),
)

For

modules(
module("One module"),
modules("Nested Modules", module("Output 1"), module("Output 2")),
module("Another module"),
modules("Nested Modules 2", module("Output 3"), module("Output 4"))
)
nikolas-burkoff commented 1 year ago

Useful code to add navbar structure from teal_modules object

mapply(
  function(mod, mod_name) {
    if (is(mod, "teal_modules")){
      insertTab("navpage", tab = navbarMenu(title = mod$label, menuName = mod_name))
      lapply(names(mod$children), function(m, menu) {
        appendTab(
          "navpage",
          tab = tabPanel(
            title = mod$children[[m]]$label,
            id = m,
            value = m
            # tab content here
          ), menuName = menu)
      }, menu = mod_name)
    }
    else {
      insertTab(
        "navpage",
        tab = tabPanel(
          title = mod$label,
          id = mod_name,
          value = id
          # tab content here
        )
      )
    }
  },
  mod = modules$children,
  mod_name = names(modules$children)
)
gogonzo commented 1 year ago

This requires to move calls filter-panel modules from single call to multiple. I've explored the possibility and it's possible with couple tweaks.

Test on the branches listed above (remove filter button doesn't work there yet)

Sys.setenv(TEAL.LOG_LEVEL = "TRACE")
pkgload::load_all("teal.slice")
pkgload::load_all("teal")
library(scda)

app <- init(
  data = cdisc_data(
    scda_cdisc_dataset_connector("ADSL")
  ),
  modules = modules(
    modules(
      label = "Nested modules",
      example_module("Example 1"),
      example_module("Example 2")
    ),
    example_module("stand-alone-module")
  ),
  title = "New style teal app"
)

shinyApp(app$ui, app$server)