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

Expose Inputs #337

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

Expose Inputs #337

wants to merge 14 commits into from

Conversation

JohnCoene
Copy link
Member

This PR addresses #315: exposing inputs when the dashboard is locked.

image

This is a custom Shiny input, by default the input is hidden when blockr is locked.

If the input is selected to be shown when locked it will be displayed above blocks in the stack on lock. This is stored in a always_shown attribute on the field.

image

See inst/examples/lock/app.R for an example.

library(blockr)

stack <- new_stack(data_block)
id <- "mystack"

shiny::shinyApp(
  ui = bslib::page_fluid(
    shiny::actionButton("lock", "Lock stacks"),
    generate_ui(stack, id)
  ),
  server = function(input, output, session) {
    shiny::observeEvent(input$lock, {
      lock()
    })

    vals <- reactiveValues(new_block = NULL)
    stack <- generate_server(
      stack,
      id,
      new_block = reactive(vals$new_block)
    )

    observeEvent(input$add, {
      vals$new_block <- NULL
      # Always append to stack
      loc <- length(stack$blocks)
      block <- available_blocks()[[input$selected_block]]
      # add_block expect the current stack, the block to add and its position
      # (NULL is fine for the position, in that case the block will
      # go at the end)
      vals$new_block <- list(
        block = block,
        position = loc
      )
    })
  }
)

@JohnCoene JohnCoene self-assigned this Mar 11, 2024
@JohnCoene JohnCoene marked this pull request as draft March 11, 2024 12:50
Copy link

codecov bot commented Mar 11, 2024

Codecov Report

Attention: Patch coverage is 86.66667% with 4 lines in your changes are missing coverage. Please review.

Project coverage is 79.20%. Comparing base (6c39b66) to head (a915196).

Files Patch % Lines
R/field-core.R 75.00% 3 Missing ⚠️
R/lock.R 87.50% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #337      +/-   ##
==========================================
+ Coverage   79.17%   79.20%   +0.03%     
==========================================
  Files          20       20              
  Lines        2122     2150      +28     
==========================================
+ Hits         1680     1703      +23     
- Misses        442      447       +5     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@JohnCoene
Copy link
Member Author

I would prefer to place the input within the label but it seems not to work, see issue and PR I opened.

rstudio/shiny#3995
rstudio/shiny#3996

@JohnCoene
Copy link
Member Author

JohnCoene commented Apr 23, 2024

This now seems to work just fine for me, feel free to let me know what you think of this proposed solution.

EDIT: the idea is to render the blocks as normal but, for inputs that have been flagged as having to be shown when locked move them up in the stack so they are outside the collapsible.

@DivadNojnarg
Copy link
Collaborator

Thanks for looking into this.

If I understood correctly, the blockr app admin would manually toggle inputs users want to see, lock the stack and share the link with users?

I am concerned about the way to scale to a real use case, say a workspace with 5 stacks each having 5 blocks and 2-3 inputs per block. Do we want to have/expose a programmatic way/api to initialise the workspace with tagged/untagged inputs so we don't have to manually toggle them?

We have a settings param available for the workspace, which could be used to pass such configuration down to the stack/block/field.

The difficulty I see right now is how to efficiently route which setting to which stack/block/field, as block ids are randomly generated. In a near future, as we plan to be able to create block outside the stack with PR #367, we can also control which name we give to them when we instantiate (from branch 110-1-no-data):

blk <- dataset_block(name = "plop")
blk
$dataset
$value
[1] "airquality"

$choices
 [1] "airquality"       "anscombe"         "attenu"           "attitude"
...          

$multiple
[1] FALSE

attr(,"type")
[1] "literal"
attr(,"class")
[1] "select_field" "field"       
attr(,"title")
[1] "Dataset"
attr(,"descr")
[1] ""
attr(,"status")
[1] "active"
attr(,"exclude")
[1] FALSE

attr(,"name")
[1] "plop" <BLOCK_ID>
attr(,"expr")
get(.(dataset), envir = as.environment("package:datasets"))
attr(,"class")
[1] "dataset_block" "data_block"    "block" 

Assuming, we can wait for PR #367 and another PR to support instantiating a stack from a list of blocks (in addition to block constructors), we could then do something like this:

blk <- dataset_block(name = "plop")

stacks <- lapply(
    1:3, 
    \(x) new_stack(blk, name = sprintf("stack%s", x))
)

do.call(
    set_workspace, 
    args = c(
        stacks, 
        list(
            title = "My workspace",
            settings = list(
                inputs_state = list(
                    "stack1-plop-dataset" = "locked",
                    "stack2-plop-dataset" = "locked",
                    "stack3-plop-dataset" = "unlocked" # OR leave NULL
                )
            )
        )
    )
)

serve_workspace(clear = FALSE)

Then you'd need some logic at the block/field level (?) to handle the inputs_state list and see whether the current field needs to be tagged.

Do you have suggestions @nbenn?

@JohnCoene JohnCoene marked this pull request as ready for review May 13, 2024 07:42
@JohnCoene JohnCoene mentioned this pull request May 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants