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

Better add blocks #413

Merged
merged 24 commits into from
Sep 11, 2024
Merged
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: blockr
Title: A block-based framework for data manipulation and visualization
Version: 0.0.2.9000
Version: 0.0.2.9010
Authors@R:
c(person(given = "Nicolas",
family = "Bennett",
@@ -23,7 +23,7 @@ URL: https://blockr-org.github.io/blockr, https://blockr-org.github.io/blockr/
License: GPL (>= 3)
Encoding: UTF-8
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.3.1.9000
RoxygenNote: 7.3.2
Imports:
magrittr,
shiny,
@@ -39,7 +39,8 @@ Imports:
shinyFiles,
memuse,
haven,
rlang
rlang,
shinyWidgets
Remotes:
blockr-org/blockr.data,
DivadNojnarg/DiagrammeR
5 changes: 5 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
@@ -4,6 +4,8 @@ S3method("value<-",field)
S3method("value<-",filesbrowser_field)
S3method("value<-",list_field)
S3method("value<-",upload_field)
S3method(add_block_server,default)
S3method(add_block_ui,default)
S3method(block_body,block)
S3method(block_code,block)
S3method(block_combiner,plot_block)
@@ -132,6 +134,7 @@ S3method(value,variable_field)
export("%>%")
export("value<-")
export(add_block)
export(add_block_server)
export(add_block_ui)
export(add_workspace_stack)
export(as_log_level)
@@ -159,7 +162,9 @@ export(from_json)
export(generate_code)
export(generate_server)
export(generate_ui)
export(get_compatible_blocks)
export(get_field_name)
export(get_registry)
export(get_stack_name)
export(get_stack_title)
export(get_workspace)
20 changes: 20 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,31 @@
# blockr 0.0.2.9000

## Feature
- Improved __add__ new block.
- Added new `category` to the registry. Now when a block is registered, you may pass a category parameter (which is used by the add block feature to sort blocks):

```r
register_block(
constructor = new_tail_block,
name = "tail block",
description = "return last n rows",
category = "transform",
classes = c("tail_block", "transform_block"),
input = "data.frame",
output = "data.frame"
)
```

If not passed, the block will belong to `uncategorized` blocks (default).

## Doc
- Improved `registry` and `getting started` vignettes.
- Add new `case studies` vignette to present blockr in various contexts.
- Refine GitHub readme.

## Fixes
- Fix issue in `handle_remove.block`: `vals$stack` wasn't correctly updated
when the last block was removed leading to wrong state.
- Loading spinner is now correctly hidden when the block visual is updated.

# blockr 0.0.2
86 changes: 76 additions & 10 deletions R/registry.R
Original file line number Diff line number Diff line change
@@ -43,17 +43,19 @@ block_name <- block_descrs_getter(block_descr_getter("name"))
block_descr <- block_descrs_getter(block_descr_getter("description"))

new_block_descr <- function(constructor, name, description, classes, input,
output, pkg) {
output, pkg, category) {

stopifnot(
is.function(constructor), is_string(name), is_string(description),
is_string(category),
is.character(classes), length(classes) >= 1L,
is_string(input), is_string(output), is_string(pkg)
)

structure(
constructor, name = name, description = description, classes = classes,
input = input, output = output, package = pkg, class = "block_descr"
constructor, name = name, description = description,
classes = classes, input = input, output = output,
package = pkg, category = category, class = "block_descr"
)
}

@@ -64,14 +66,24 @@ block_registry <- new.env()
#' @param classes Block classes
#' @param input,output Object types the block consumes and produces
#' @param package Package where block is defined
#' @param category Useful to sort blocks by topics. If not specified,
#' blocks are uncategorized.
#'
#' @rdname available_blocks
#' @export
register_block <- function(constructor, name, description, classes, input,
output, package = NA_character_) {
register_block <- function(
constructor,
name,
description,
classes,
input,
output,
package = NA_character_,
category = "uncategorized"
) {

descr <- new_block_descr(constructor, name, description, classes, input,
output, package)
output, package, category)

id <- classes[1L]

@@ -85,8 +97,16 @@ register_block <- function(constructor, name, description, classes, input,
#' @param ... Forwarded to `register_block()`
#' @rdname available_blocks
#' @export
register_blocks <- function(constructor, name, description, classes, input,
output, package = NA_character_) {
register_blocks <- function(
constructor,
name,
description,
classes,
input,
output,
package = NA_character_,
category = "uncategorized"
) {

if (length(constructor) == 1L && !is.list(classes)) {
classes <- list(classes)
@@ -100,7 +120,8 @@ register_blocks <- function(constructor, name, description, classes, input,
classes = classes,
input = input,
output = output,
package = package
package = package,
category = category
)

invisible(res)
@@ -256,7 +277,25 @@ register_blockr_blocks <- function(pkg) {
"data.frame",
"data.frame"
),
package = pkg
package = pkg,
category = c(
"data",
"data",
"data",
"data",
"parser",
"parser",
"parser",
"parser",
"transform",
"transform",
"transform",
"transform",
"transform",
"transform",
"transform",
"transform"
)
)
}

@@ -273,3 +312,30 @@ construct_block <- function(block, ...) {

block(...)
}

#' List available blocks as a data.frame
#'
#' Provides an alternate way of displaying
#' the registry information.
#' This can be useful to create dynamic UI elements
#' like in \link{add_block_ui}.
#'
#' @return A dataframe.
#'
#' @export
get_registry <- function() {
res <- lapply(seq_along(available_blocks()), \(i) {
blk <- available_blocks()[[i]]
attrs <- attributes(blk)
data.frame(
ctor = names(available_blocks())[[i]],
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do you need to expose a name for the constructor here? The names here are just the names used for constructor bindings in the block_registry environment. If a result_block is called result_block in this environment, this is to be treated more as a coincidence than a "rule".

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That's an artifact I needed for the accotdions and pills but we don't need anymore with the new virtual select. To cleanup.

description = attrs[["description"]],
category = attrs[["category"]],
classes = paste(c(attrs[["classes"]], "block"), collapse = ", "),
input = attrs[["input"]],
output = attrs[["output"]],
package = attrs[["package"]]
)
})
do.call(rbind, res)
}
Loading