Skip to content

Commit 99c9867

Browse files
peymaneshghikpagaczgithub-actions[bot]
authored
feat: added utility wrappers for access management with rAccess
Co-authored-by: Konrad Pagacz <konrad.pagacz@gmail.com> Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
1 parent 4f09070 commit 99c9867

File tree

13 files changed

+672
-7
lines changed

13 files changed

+672
-7
lines changed

.Rbuildignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,9 @@
22
^\.lintr
33
^docs/
44
^\_pkgdown\.yml
5+
^.*\.Rproj$
6+
^\.Rproj\.user$
7+
^_pkgdown\.yml$
8+
^docs$
9+
^pkgdown$
10+
^\.github$

.github/workflows/pkgdown.yaml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
---
2+
name: Docs 📚
3+
4+
on:
5+
push:
6+
branches:
7+
- main
8+
paths:
9+
- "inst/templates/**"
10+
- "_pkgdown.*"
11+
- DESCRIPTION
12+
- "**.md"
13+
- "**.Rmd"
14+
- "man/**"
15+
- "LICENSE.*"
16+
- NAMESPACE
17+
pull_request:
18+
types:
19+
- opened
20+
- synchronize
21+
- reopened
22+
- ready_for_review
23+
branches:
24+
- main
25+
paths:
26+
- "inst/templates/**"
27+
- "_pkgdown.*"
28+
- DESCRIPTION
29+
- "**.md"
30+
- "**.Rmd"
31+
- "man/**"
32+
- "LICENSE.*"
33+
- NAMESPACE
34+
workflow_dispatch:
35+
36+
jobs:
37+
docs:
38+
name: Pkgdown Docs 📚
39+
uses: insightsengineering/r.pkg.template/.github/workflows/pkgdown.yaml@main
40+
secrets:
41+
REPO_GITHUB_TOKEN: ${{ secrets.REPO_GITHUB_TOKEN }}
42+
with:
43+
default-landing-page: latest-tag
44+
additional-unit-test-report-directories: unit-test-report-non-cran
45+
deps-installation-method: setup-r-dependencies

DESCRIPTION

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
Package: uteals
22
Title: Decorators and transformators for `teal` modules
3+
Language: en-US
34
Version: 0.0.0.9000
45
Date: 2025-10-12
56
URL: https://github.com/phuse-org/uteals
@@ -15,7 +16,8 @@ Authors@R:
1516
person("Konrad", "Pagacz", , "konrad.pagacz@gmail.com", role = "aut"),
1617
person(given = "PHUSE", role = "cph")
1718
)
18-
Description: Provides transformator and decorator modules extending the features of other `teal` modules.
19+
Description: Provides common decorators and transformators, and other utility
20+
functions to extends 'teal' framework.
1921
License: MIT + file LICENSE
2022
Encoding: UTF-8
2123
Roxygen: list(markdown = TRUE)
@@ -41,10 +43,15 @@ Imports:
4143
shinyjs,
4244
teal,
4345
teal.code,
44-
tern
46+
tern,
47+
yaml
4548
Suggests:
4649
forcats,
50+
knitr,
51+
rAccess,
52+
rmarkdown,
4753
teal.data,
48-
teal.modules.general,
4954
teal.modules.clinical,
55+
teal.modules.general,
5056
teal.transform
57+
VignetteBuilder: knitr

NAMESPACE

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
# Generated by roxygen2: do not edit by hand
22

33
export(create_rel_risk_transformator)
4+
export(extract_modules_to_yaml)
45
export(forestplot_x_decorator)
56
export(g_forest_with_transform)
67
export(ggplot_decorator)
8+
export(keep_by_label)
79
export(merge_levels_transformator)
810
export(or_filtering_transformator)
911
export(patchwork_plot_decorator)
12+
export(remove_by_label)
1013
export(title_footer_decorator)
1114
import(checkmate)
1215
import(dplyr)
@@ -21,6 +24,7 @@ import(shinyBS)
2124
import(shinyWidgets)
2225
import(teal)
2326
import(tern)
27+
import(yaml)
2428
importFrom(cowplot,plot_grid)
2529
importFrom(grDevices,graphics.off)
2630
importFrom(methods,new)

R/r_access_utilities.R

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
#' Extract Non-Parent Module Labels to `YAML`
2+
#'
3+
#' @description `r lifecycle::badge("experimental")`
4+
#' Extracts module labels from a teal modules object, filters out parent modules
5+
#' (grouping containers), and generates a `YAML` file with the functional modules.
6+
#'
7+
#' @param mods (`teal_module` or `teal_modules`) a teal modules object
8+
#' containing the module structure.
9+
#' @param filepath (`character(1)`) character string specifying the output `YAML` file path.
10+
#'
11+
#' @return Character vector of non-parent module labels
12+
#'
13+
#' @import yaml
14+
#' @examples
15+
#' # Extract modules from mods object to YAML file
16+
#' mods <- teal::modules(
17+
#' teal::example_module("mod1"),
18+
#' teal::example_module("mod2")
19+
#' )
20+
#' labels <- extract_modules_to_yaml(mods, "panel_str_modules.yml")
21+
#'
22+
#' @export
23+
extract_modules_to_yaml <- function(mods, filepath) {
24+
# Recursively extract module labels, excluding parent containers
25+
extract_labels <- function(mod_obj) {
26+
labels <- character(0)
27+
28+
if (inherits(mod_obj, "teal_module")) {
29+
# This is a leaf module - extract its label
30+
return(mod_obj$label)
31+
} else if (inherits(mod_obj, "teal_modules")) {
32+
# This is a container - recurse into children
33+
for (child in mod_obj$children) {
34+
labels <- c(labels, extract_labels(child))
35+
}
36+
}
37+
38+
labels
39+
}
40+
41+
# Extract all non-parent module labels
42+
non_parent_labels <- extract_labels(mods)
43+
44+
# Create panel_str structure
45+
panel_str <- list(
46+
list(access_panel = "ADMIN"),
47+
list(
48+
access_panel = "Modules",
49+
access_units = lapply(non_parent_labels, function(label) list(unit = label))
50+
)
51+
)
52+
53+
# Write to YAML file
54+
writeLines(yaml::as.yaml(list(panel_str = panel_str)), filepath)
55+
56+
cat("Generated", filepath, "with", length(non_parent_labels), "non-parent module labels\n")
57+
non_parent_labels
58+
}
59+
60+
#' Filter Teal Modules by Label
61+
#'
62+
#' @description `r lifecycle::badge("experimental")`
63+
#' Recursively filters a teal modules object to keep only modules whose labels
64+
#' match the specified labels. Removes modules that don't match and empty
65+
#' parent containers.
66+
#'
67+
#' @param x (`teal_module` or `teal_modules`) the object to filter.
68+
#' @param label (`character(1)`) character vector of module labels to keep.
69+
#'
70+
#' @return Filtered `teal_modules` or `teal_module` object, or `NULL` if none matches.
71+
#'
72+
#' @import checkmate
73+
#' @examples
74+
#' # Keep only specific modules by label
75+
#' mods <- teal::modules(
76+
#' teal::example_module("mod1"),
77+
#' teal::example_module("mod2")
78+
#' )
79+
#' filtered_mods <- keep_by_label(mods, c("Data Table", "Disposition"))
80+
#'
81+
#' @export
82+
keep_by_label <- function(x, label) {
83+
checkmate::assert_multi_class(x, c("teal_modules", "teal_module"))
84+
if (inherits(x, "teal_modules")) {
85+
x$children <- Filter(
86+
length,
87+
lapply(x$children, keep_by_label, label = label)
88+
)
89+
if (length(x$children) == 0) {
90+
return(NULL)
91+
}
92+
return(x)
93+
}
94+
if (x$label %in% label) {
95+
return(x)
96+
}
97+
NULL
98+
}
99+
100+
#' Remove Teal Modules by Label
101+
#'
102+
#' @description `r lifecycle::badge("experimental")`
103+
#' Recursively removes modules from a teal modules structure that match the specified labels.
104+
#'
105+
#' @param x (`teal_module` or `teal_modules`) The object to filter.
106+
#' @param label (`character(1)`) character vector of module labels to remove.
107+
#'
108+
#' @return The filtered teal modules object with matching modules removed, or `NULL`
109+
#' if all modules are removed.
110+
#'
111+
#' @import checkmate
112+
#' @examples
113+
#' mods <- teal::modules(
114+
#' teal::example_module("mod1"),
115+
#' teal::example_module("mod2")
116+
#' )
117+
#' # Remove a single module
118+
#' filtered_mods <- remove_by_label(mods, "Deaths")
119+
#'
120+
#' # Remove multiple modules
121+
#' filtered_mods <- remove_by_label(mods, c("Deaths", "Lab Summary Table"))
122+
#'
123+
#' @export
124+
remove_by_label <- function(x, label) {
125+
checkmate::assert_multi_class(x, c("teal_modules", "teal_module"))
126+
127+
# Check if label exists and matches
128+
if (!is.null(x$label) && length(x$label) > 0 && x$label %in% label) {
129+
return(NULL)
130+
}
131+
132+
if (inherits(x, "teal_modules")) {
133+
x$children <- Filter(
134+
function(child) !is.null(child),
135+
lapply(x$children, remove_by_label, label = label)
136+
)
137+
if (length(x$children) == 0) {
138+
return(NULL)
139+
}
140+
}
141+
142+
x
143+
}

README.md

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,30 @@
1-
# uteals
1+
# `uteals`
22

3-
An R package that provides utility functions and wrappers to complement the [teal package](https://cran.r-project.org/package=teal) from CRAN.
3+
[![Lifecycle:Experimental](https://img.shields.io/badge/Lifecycle-Experimental-blue?style=flat)](https://github.com/phuse-org/uteals/)
4+
5+
An R package that provides common decorators, transformators, and utility
6+
functions to enhance the [`teal` package](https://cran.r-project.org/package=teal) ecosystem.
7+
8+
## Installation
9+
10+
```r
11+
# Install from GitHub
12+
devtools::install_github("phuse-org/uteals")
13+
```
414

515
## Development Status
616

717
This package is currently under development.
18+
Please see [references](phuse-org.github.io/uteals/)
19+
and [vignettes](https://phuse-org.github.io/uteals/articles/)
20+
for latest available features.
821

922
## About
1023

11-
The uteals package is being developed by the **Teal Enhancements for Industry Adoption** PHUSE working group. For more information about this initiative, visit: https://advance.hub.phuse.global/wiki/spaces/WEL/pages/30441473/Teal+Enhancements+for+Cross-Industry+Adoption
24+
The `uteals` package is being developed by the **Teal Enhancements for Industry Adoption** PHUSE working group.
25+
For more information about this initiative,
26+
visit [`PHUSE` website](https://advance.hub.phuse.global/wiki/spaces/WEL/pages/30441473/Teal+Enhancements+for+Cross-Industry+Adoption).
1227

1328
## Contributing
1429

15-
We encourage the open source community to join this effort and contribute to the development of uteals.
30+
We encourage the open source community to join this effort and contribute to the development of `uteals`.

_pkgdown.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ reference:
1818
- title: Transformators
1919
contents:
2020
- ends_with("transformator")
21+
- title: Access Management
22+
contents:
23+
- extract_modules_to_yaml
24+
- keep_by_label
25+
- remove_by_label
2126
- title: Utility functions
2227
contents:
2328
- g_forest_with_transform

inst/WORDLIST

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ dropdown
22
transformator
33
transformators
44
UI
5+
Lifecycle

man/extract_modules_to_yaml.Rd

Lines changed: 31 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/keep_by_label.Rd

Lines changed: 31 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)