Skip to content

Commit bd9d8e0

Browse files
Merge pull request #122 from openpharma/ac-96
Improved Excel button
2 parents 37d556e + 130b274 commit bd9d8e0

19 files changed

+610
-18
lines changed

Diff for: DESCRIPTION

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
Package: clinsight
22
Title: ClinSight
33
Version: 0.1.0.9008
4+
DevexVersion: 9000
45
Authors@R: c(
56
person("Leonard Daniël", "Samson", , "[email protected]", role = c("cre", "aut"),
67
comment = c(ORCID = "0000-0002-6252-7639")),

Diff for: NEWS.md

+4
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313

1414
- When using the `shinyproxy` deployment configuration, the user name is now expected to be base64 encoded, and will now be base64 encoded by `clinsight` by default, so that the app can also handle non-ASCII signs in user names that are stored in HTTP headers. To display the user name correctly, use base64 encoding in the `application.yml` in ShinyProxy settings (for example: `http-headers.X_SP_USERNAME: "#{T(java.util.Base64).getEncoder().encodeToString(oidcUser.getFullName().getBytes())}"`).
1515

16+
## `devex` changes
17+
- Added `Excel` download button to Queries table & patient listings that need review.
18+
- Added helper function to automatically determine when adding said excel button is appropriate.
19+
1620
# clinsight 0.1.0
1721

1822
## Changed

Diff for: R/fct_data_helpers.R

+29
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,35 @@ add_missing_columns <- function(
505505
data
506506
}
507507

508+
#' Configure DT helper
509+
#'
510+
#' Small wrapper that helps handle some messiness preparing the correct `DT`
511+
#' dom, extensions, & options when needed. Specifically, when & how to add an
512+
#' Excel download button.
513+
#'
514+
#' @param data A data frame used for display in a DT table. Number of rows will
515+
#' be assessed
516+
#' @param table_name character string, usually the form name
517+
#'
518+
#' @keywords internal
519+
#' @return list with three named objects: `dom`, `exts`, and `opts`
520+
dt_config <- function(data, table_name = "form") {
521+
default_args<- formals(datatable_custom)
522+
if(nrow(data) > 0 & isTRUE(get_golem_config("allow_listing_download"))) {
523+
dt_dom <- 'Bfti'
524+
dt_exts <- c("Buttons", eval(default_args$extensions))
525+
dt_opts <- list(buttons=list(list(extend = 'excel',
526+
text = '<i class="fa-solid fa-download"></i>',
527+
filename = paste("clinsight", gsub(" ", "-", table_name), sep = ".")
528+
)))
529+
} else {
530+
dt_dom <- default_args$dom |> eval()
531+
dt_exts <- default_args$extensions |> eval()
532+
dt_opts <- default_args$options |> eval()
533+
}
534+
return(list(dom = dt_dom, exts = dt_exts, opts = dt_opts))
535+
}
536+
508537
#' Custom interactive datatable
509538
#'
510539
#' Small wrapper around [DT::datatable()]. Will be used to create tables in a

Diff for: R/mod_common_forms.R

+18-4
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,16 @@ mod_common_forms_server <- function(
132132
)) |>
133133
adjust_colnames("^SAE ")
134134
if(!input$show_all_data) SAE_data$subject_id <- NULL
135-
datatable_custom(SAE_data, rename_vars = table_names, rownames= FALSE,
136-
title = "Serious Adverse Events", escape = FALSE)
135+
136+
# determine DT dom / exts / opts
137+
DT <- dt_config(SAE_data,
138+
table_name = paste("SAE", ifelse(input$show_all_data,
139+
"all_patients", r$subject_id), sep = "."))
140+
datatable_custom(
141+
SAE_data, rename_vars = table_names, rownames= FALSE,
142+
title = "Serious Adverse Events", escape = FALSE,
143+
dom = DT$dom, extensions = DT$exts, options = DT$opts
144+
)
137145
})
138146

139147
output[["common_form_table"]] <- DT::renderDT({
@@ -145,8 +153,14 @@ mod_common_forms_server <- function(
145153
dplyr::select(-dplyr::starts_with("SAE"))
146154
}
147155
if(!input$show_all_data) df$subject_id <- NULL
148-
datatable_custom(df, rename_vars = table_names, rownames= FALSE,
149-
title = form, escape = FALSE)
156+
157+
# determine DT dom / exts / opts
158+
DT <- dt_config(df,
159+
table_name = paste(form, ifelse(input$show_all_data,
160+
"all_patients", r$subject_id), sep = "."))
161+
datatable_custom(
162+
df, rename_vars = table_names, rownames= FALSE,title = form,
163+
escape = FALSE, dom = DT$dom, extensions = DT$exts, options = DT$opts)
150164
})
151165

152166
})

Diff for: R/mod_queries.R

+7-1
Original file line numberDiff line numberDiff line change
@@ -144,11 +144,17 @@ mod_queries_server <- function(id, r, navinfo, all_forms, db_path, table_names){
144144
query_cols <- c("resolved", query_cols)
145145
table_title <- "All queries"
146146
}
147+
148+
# determine DT dom / exts / opts
149+
DT <- dt_config(initial_queries()[query_cols],
150+
table_name = paste(ifelse(input$show_resolved, "all", "open"),
151+
"queries", sep = "."))
147152
datatable_custom(
148153
initial_queries()[query_cols],
149154
table_names,
150155
title = table_title,
151-
callback = dblclick_to_form(ns("go_to_form"))
156+
callback = dblclick_to_form(ns("go_to_form")),
157+
dom = DT$dom, extensions = DT$exts, options = DT$opts
152158
)
153159
})
154160

Diff for: R/mod_study_forms.R

+6-1
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,12 @@ mod_study_forms_server <- function(
223223

224224
output[["table"]] <- DT::renderDT({
225225
req(table_data_active())
226-
datatable_custom(table_data_active(), table_names, escape = FALSE)
226+
# determine DT dom / exts / opts
227+
DT <- dt_config(table_data_active(),
228+
table_name = paste(form, ifelse(input$show_all,
229+
"all_patients", r$subject_id), sep = "."))
230+
datatable_custom(table_data_active(), table_names, escape = FALSE,
231+
dom = DT$dom, extensions = DT$exts, options = DT$opts)
227232
})
228233

229234
if(form %in% c("Vital signs", "Vitals adjusted")){

Diff for: inst/app/www/custom.css

+5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11

2+
.dataTables_wrapper .dt-buttons {
3+
padding-left: 0.75em;
4+
float: right;
5+
}
6+
27
.bslib-value-box .value-box-area {
38
padding: 0.1rem 0rem 0.1rem 1rem;
49
}

Diff for: inst/golem-config.yml

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ default:
1111
Medical Monitor: medical_monitor
1212
Data Manager: data_manager
1313
allow_to_review: [admin, medical_monitor]
14+
allow_listing_download: TRUE
1415
dev:
1516
golem_wd: !expr golem::pkg_path()
1617
test:

Diff for: man/dt_config.Rd

+23
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: tests/testthat/_snaps/app_feature_01/app-feature-1-002.json

+43-1
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@
239239
"filter": "none",
240240
"vertical": false,
241241
"extensions": [
242+
"Buttons",
242243
"Scroller",
243244
"ColReorder"
244245
],
@@ -251,8 +252,15 @@
251252
"scrollResize": true,
252253
"scrollCollapse": true,
253254
"colReorder": true,
255+
"buttons": [
256+
{
257+
"extend": "excel",
258+
"text": "<i class=\"fa-solid fa-download\"><\/i>",
259+
"filename": "clinsight.Adverse-events.BEL_04_772"
260+
}
261+
],
254262
"initComplete": "function() {\n$(this.api().table().container()).find('.header').html(\"Adverse events\")\n}",
255-
"dom": "f<\"header h5\">ti",
263+
"dom": "Bf<\"header h5\">ti",
256264
"columnDefs": [
257265
{
258266
"className": "dt-right",
@@ -389,6 +397,40 @@
389397
"attachment": null,
390398
"all_files": true
391399
},
400+
{
401+
"name": "jszip",
402+
"version": "1.13.6",
403+
"src": {
404+
"href": "jszip-1.13.6"
405+
},
406+
"meta": null,
407+
"script": "jszip.min.js",
408+
"stylesheet": null,
409+
"head": null,
410+
"attachment": null,
411+
"package": null,
412+
"all_files": false
413+
},
414+
{
415+
"name": "dt-ext-buttons-bootstrap5",
416+
"version": "1.13.6",
417+
"src": {
418+
"href": "dt-ext-buttons-bootstrap5-1.13.6"
419+
},
420+
"meta": null,
421+
"script": [
422+
"js/dataTables.buttons.min.js",
423+
"js/buttons.html5.min.js",
424+
"js/buttons.colVis.min.js",
425+
"js/buttons.print.min.js",
426+
"js/buttons.bootstrap5.min.js"
427+
],
428+
"stylesheet": "css/buttons.bootstrap5.min.css",
429+
"head": null,
430+
"attachment": null,
431+
"package": null,
432+
"all_files": false
433+
},
392434
{
393435
"name": "dt-ext-scroller-bootstrap5",
394436
"version": "1.13.6",

Diff for: tests/testthat/_snaps/app_feature_01/app-feature-1-003.json

+43-1
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@
239239
"filter": "none",
240240
"vertical": false,
241241
"extensions": [
242+
"Buttons",
242243
"Scroller",
243244
"ColReorder"
244245
],
@@ -251,8 +252,15 @@
251252
"scrollResize": true,
252253
"scrollCollapse": true,
253254
"colReorder": true,
255+
"buttons": [
256+
{
257+
"extend": "excel",
258+
"text": "<i class=\"fa-solid fa-download\"><\/i>",
259+
"filename": "clinsight.Adverse-events.BEL_04_772"
260+
}
261+
],
254262
"initComplete": "function() {\n$(this.api().table().container()).find('.header').html(\"Adverse events\")\n}",
255-
"dom": "f<\"header h5\">ti",
263+
"dom": "Bf<\"header h5\">ti",
256264
"columnDefs": [
257265
{
258266
"className": "dt-right",
@@ -389,6 +397,40 @@
389397
"attachment": null,
390398
"all_files": true
391399
},
400+
{
401+
"name": "jszip",
402+
"version": "1.13.6",
403+
"src": {
404+
"href": "jszip-1.13.6"
405+
},
406+
"meta": null,
407+
"script": "jszip.min.js",
408+
"stylesheet": null,
409+
"head": null,
410+
"attachment": null,
411+
"package": null,
412+
"all_files": false
413+
},
414+
{
415+
"name": "dt-ext-buttons-bootstrap5",
416+
"version": "1.13.6",
417+
"src": {
418+
"href": "dt-ext-buttons-bootstrap5-1.13.6"
419+
},
420+
"meta": null,
421+
"script": [
422+
"js/dataTables.buttons.min.js",
423+
"js/buttons.html5.min.js",
424+
"js/buttons.colVis.min.js",
425+
"js/buttons.print.min.js",
426+
"js/buttons.bootstrap5.min.js"
427+
],
428+
"stylesheet": "css/buttons.bootstrap5.min.css",
429+
"head": null,
430+
"attachment": null,
431+
"package": null,
432+
"all_files": false
433+
},
392434
{
393435
"name": "dt-ext-scroller-bootstrap5",
394436
"version": "1.13.6",

0 commit comments

Comments
 (0)