Skip to content

Commit

Permalink
Merge pull request #160 from openpharma/jt-make_row_review_more_effic…
Browse files Browse the repository at this point in the history
…ient

Improve row review a little
  • Loading branch information
LDSamson authored Feb 20, 2025
2 parents 00172f0 + 7f03477 commit 2145018
Show file tree
Hide file tree
Showing 11 changed files with 158 additions and 109 deletions.
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: clinsight
Title: ClinSight
Version: 0.1.1.9020
Version: 0.1.1.9021
Authors@R: c(
person("Leonard Daniël", "Samson", , "[email protected]", role = c("cre", "aut"),
comment = c(ORCID = "0000-0002-6252-7639")),
Expand Down
106 changes: 68 additions & 38 deletions R/mod_common_forms.R
Original file line number Diff line number Diff line change
Expand Up @@ -97,58 +97,88 @@ mod_common_forms_server <- function(
moduleServer( id, function(input, output, session){
ns <- session$ns

common_form_data <- reactiveVal()
SAE_data <- reactiveVal()
observe({
df <- {
common_form_data <- reactive({
golem::cat_dev(form, "data computed \n")
shiny::validate(need(
!is.null(r$filtered_data[[form]]),
paste0("Warning: no data found in the database for the form '", form, "'.")
))
df <-
dplyr::left_join(
r$filtered_data[[form]],
with(r$review_data, r$review_data[item_group == form, ]) |>
dplyr::select(-dplyr::all_of(c("edit_date_time", "event_date"))),
by = id_item
) |>
dplyr::mutate(
item_value = ifelse(
reviewed == "No",
paste0("<b>", htmltools::htmlEscape(item_value), "*</b>"),
htmltools::htmlEscape(item_value)
)
) |>
create_table(expected_columns = names(form_items)) |>
dplyr::mutate(o_reviewed = Map(\(x, y, z) append(x, list(
row_id = y,
disabled = z,
updated = isolate(session$userData$update_checkboxes[[form]]))
),
o_reviewed,
dplyr::row_number(),
subject_id != r$subject_id))
if(form == "Adverse events") {
df |>
dplyr::filter(!grepl("Yes", `Serious Adverse Event`)
) |>
dplyr::select(-dplyr::starts_with("SAE"))
} else {
df
}
})

if (form == "Adverse events") {
SAE_data <- reactive({
shiny::validate(need(
!is.null(r$filtered_data[[form]]),
paste0("Warning: no data found in the database for the form '", form, "'.")
))
golem::cat_dev("SAE data computed \n")
dplyr::left_join(
r$filtered_data[[form]],
with(r$review_data, r$review_data[item_group == form, ]) |>
dplyr::select(-dplyr::all_of(c("edit_date_time", "event_date"))),
with(r$review_data, r$review_data[item_group == form, ]) |>
dplyr::select(-dplyr::all_of(c("edit_date_time", "event_date"))),
by = id_item
) |>
) |>
dplyr::mutate(
item_value = ifelse(
reviewed == "No",
paste0("<b>", htmltools::htmlEscape(item_value), "*</b>"),
reviewed == "No",
paste0("<b>", htmltools::htmlEscape(item_value), "*</b>"),
htmltools::htmlEscape(item_value)
)
) |>
create_table(expected_columns = names(form_items)) |>
dplyr::mutate(o_reviewed = Map(\(x, y, z) append(x, list(
row_id = y,
disabled = z,
updated = isolate(session$userData$update_checkboxes[[form]]))
),
o_reviewed,
dplyr::row_number(),
subject_id != r$subject_id)
) |>
create_table(expected_columns = names(form_items)) |>
dplyr::mutate(o_reviewed = Map(\(x, y, z) append(x, list(row_id = y, disabled = z)),
o_reviewed,
dplyr::row_number(),
subject_id != r$subject_id))
}
common_form_data({
if(form == "Adverse events") {
df |>
dplyr::filter(!grepl("Yes", `Serious Adverse Event`)
) |>
dplyr::select(-dplyr::starts_with("SAE"))
} else {
df
}
dplyr::filter(grepl("Yes", `Serious Adverse Event`)) |>
dplyr::select(dplyr::any_of(
c("o_reviewed", "subject_id","form_repeat", "Name", "AESI", "SAE Start date",
"SAE End date", "CTCAE severity", "Treatment related",
"Treatment action", "Other action", "SAE Category",
"SAE Awareness date", "SAE Date of death", "SAE Death reason")
)) |>
adjust_colnames("^SAE ")
})
if (form == "Adverse events")
SAE_data({
df |>
dplyr::filter(grepl("Yes", `Serious Adverse Event`)) |>
dplyr::select(dplyr::any_of(
c("o_reviewed", "subject_id","form_repeat", "Name", "AESI", "SAE Start date",
"SAE End date", "CTCAE severity", "Treatment related",
"Treatment action", "Other action", "SAE Category",
"SAE Awareness date", "SAE Date of death", "SAE Death reason")
)) |>
adjust_colnames("^SAE ")
})
})
}

mod_review_form_tbl_server("review_form_tbl", r, common_form_data, form, reactive(input$show_all_data), table_names, form)
if (form == "Adverse events")
if (form == "Adverse events")
mod_review_form_tbl_server("review_form_SAE_tbl", r, SAE_data, form, reactive(input$show_all_data), table_names, "Serious Adverse Events")

mod_timeline_server(
Expand Down
44 changes: 27 additions & 17 deletions R/mod_review_form_tbl.R
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ mod_review_form_tbl_ui <- function(id) {
#' `review_data` will be used to determine which rows will be displayed in
#' bold and, for the form Adverse events, which timeline data should be
#' highlighted.
#' @param table_data Common reactive value. Used to manage the server data
#' displayed in the DataTable.
#' @param reactive_table_data Common reactive value. Used to manage the server
#' data displayed in the DataTable.
#' @param form A character string with the name of the form to display.
#' @param show_all Common reactive value, a logical indicating whether all
#' records should be displayed.
Expand All @@ -41,36 +41,47 @@ mod_review_form_tbl_ui <- function(id) {
mod_review_form_tbl_server <- function(
id,
r,
table_data,
reactive_table_data,
form,
show_all,
table_names = NULL,
title = NULL
){
stopifnot(is.reactivevalues(r))
stopifnot(is.reactive(table_data))
stopifnot(is.reactive(reactive_table_data))
stopifnot(is.character(form), length(form) == 1)
stopifnot(is.reactive(show_all))

moduleServer(id, function(input, output, session){
ns <- session$ns

reload_data <- reactiveVal(0)
datatable_rendered <- reactiveVal(FALSE)
datatable_rendered <- reactiveVal(NULL)
table_data <- reactiveVal()

############################### Observers: #################################

# table data manipulation code should ideally be here, then we can remove this.
# Alternatively, we can also pass this from the main module as a function argument

observe({
golem::cat_dev(form, "| Resetting userData\n")
reload_data(reload_data() + 1)
datatable_rendered(NULL)
session$userData$update_checkboxes[[form]] <- NULL
session$userData$review_records[[form]] <- data.frame(id = integer(), reviewed = character())
}) |>
bindEvent(r$subject_id, r$review_data)
bindEvent(r$subject_id, r$review_data, r$filtered_data[[form]])

observeEvent(datatable_rendered(), {
table_data(reactive_table_data())
}, ignoreInit = TRUE)

observeEvent(session$userData$update_checkboxes[[form]], {
req(datatable_rendered())
golem::cat_dev(form, "| Updating checkboxes\n")
reload_data(reload_data() + 1)
checked <- session$userData$update_checkboxes[[form]]

df <- table_data() |>
dplyr::mutate(o_reviewed = dplyr::if_else(subject_id == r$subject_id,
lapply(o_reviewed, modifyList, list(updated = checked)),
Expand All @@ -79,6 +90,8 @@ mod_review_form_tbl_server <- function(
})

observeEvent(input$table_review_selection, {
golem::cat_dev(form, "| table review selection changed to:\n")
golem::print_dev(input$table_review_selection[c("id", "reviewed")])

Check warning on line 94 in R/mod_review_form_tbl.R

View check run for this annotation

Codecov / codecov/patch

R/mod_review_form_tbl.R#L93-L94

Added lines #L93 - L94 were not covered by tests
# Update review values for session's user data
session$userData$update_checkboxes[[form]] <- NULL
session$userData$review_records[[form]] <-
Expand All @@ -103,6 +116,7 @@ mod_review_form_tbl_server <- function(
observe({
req(!is.null(show_all()))
req(table_data(), datatable_rendered())
golem::cat_dev(form, "| renewing datatable server data\n")
DT::dataTableAjax(table_proxy$session,
subset(table_data(), show_all() | subject_id == r$subject_id),
rownames = FALSE,
Expand All @@ -114,19 +128,16 @@ mod_review_form_tbl_server <- function(
observeEvent(reload_data(), {
req(!is.null(show_all()))
req(table_data(), datatable_rendered())
golem::cat_dev(form, "| reload_data() triggered\n")
DT::reloadData(table_proxy)
}, ignoreInit = TRUE)

observeEvent(r$subject_id, {
req(table_data())
reload_data(reload_data() + 1)
df <- table_data() |>
dplyr::mutate(o_reviewed = Map(\(x, y) modifyList(x, list(updated = NULL, disabled = y)), o_reviewed, subject_id != r$subject_id))
table_data(df)
})

observeEvent(show_all(), {
req(table_data(), datatable_rendered())
golem::cat_dev(
form, "| show_all() trigger changed. Incrementing reload_data()",
"and toggle showing subject_id column \n"
)
reload_data(reload_data() + 1)
index <- match("subject_id", colnames(table_data())) - 1
if (show_all()) {
Expand All @@ -139,10 +150,9 @@ mod_review_form_tbl_server <- function(
############################### Outputs: ###################################

output[["table"]] <- DT::renderDT({
req(r$filtered_data[[form]])
datatable_rendered(TRUE)
datatable_custom(
isolate(subset(table_data(), show_all() | subject_id == r$subject_id)),
subset(reactive_table_data(), isolate(show_all() | subject_id == r$subject_id)),
rename_vars = c("Review Status" = "o_reviewed", table_names),
rownames= FALSE,
title = title,
Expand Down
11 changes: 6 additions & 5 deletions R/mod_review_forms.R
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ mod_review_forms_server <- function(
bindEvent(active_form(), session$userData$review_records[[active_form()]])

observeEvent(r$subject_id, {
golem::cat_dev("mod_review_forms | Reset review records\n")
session$userData$update_checkboxes[[active_form()]] <- NULL
session$userData$review_records[[active_form()]] <- data.frame(id = integer(), reviewed = character())
})
Expand All @@ -158,8 +159,6 @@ mod_review_forms_server <- function(
observeEvent(c(active_form(), r$subject_id), {
cat("Update confirm review button\n\n\n")
req(r$review_data)
golem::cat_dev("review_data_active:\n")
golem::print_dev(review_data_active())
review_indeterminate(FALSE)
if(nrow(review_data_active()) == 0){
cat("No review data found for Subject id: ", r$subject_id,
Expand Down Expand Up @@ -270,10 +269,12 @@ mod_review_forms_server <- function(
status = ifelse(reviewed == "Yes", "old", "new")
)

golem::cat_dev("review records to add:\n")
golem::print_dev(review_records)
golem::cat_dev(
active_form(), "|", "Adjusting review status for",
length(unique(review_records$id)), "ids\n"
)

cat("write review progress to database\n")
cat("Writing review progress to database\n")
db_save_review(
review_records,
db_path = db_path,
Expand Down
58 changes: 30 additions & 28 deletions R/mod_study_forms.R
Original file line number Diff line number Diff line change
Expand Up @@ -163,35 +163,37 @@ mod_study_forms_server <- function(
dplyr::mutate(item_name = factor(item_name, levels = names(form_items)))
})

table_data <- reactiveVal()
observe({
df <- {
validate(need(
r$filtered_data[[form]],
paste0("Warning: no data found in database for the form '", form, "'")
))
dplyr::left_join(
r$filtered_data[[form]],
with(r$review_data, r$review_data[item_group == form, ]) |>
dplyr::select(-dplyr::all_of(c("edit_date_time", "event_date"))),
by = id_item
study_form_data <- reactive({
cat(form, "data computed \n")
validate(need(
r$filtered_data[[form]],
paste0("Warning: no data found in database for the form '", form, "'")
))
dplyr::left_join(
r$filtered_data[[form]],
with(r$review_data, r$review_data[item_group == form, ]) |>
dplyr::select(-dplyr::all_of(c("edit_date_time", "event_date"))),
by = id_item
) |>
dplyr::mutate(
item_value = ifelse(
reviewed == "No",
paste0("<b>", htmltools::htmlEscape(item_value), "*</b>"),
htmltools::htmlEscape(item_value)
)
) |>
dplyr::mutate(
item_value = ifelse(
reviewed == "No",
paste0("<b>", htmltools::htmlEscape(item_value), "*</b>"),
htmltools::htmlEscape(item_value)
)
) |>
create_table(expected_columns = names(form_items)) |>
dplyr::mutate(o_reviewed = Map(\(x, y, z) append(x, list(row_id = y, disabled = z)),
o_reviewed,
dplyr::row_number(),
subject_id != r$subject_id))
}
table_data(df)
create_table(expected_columns = names(form_items)) |>
dplyr::mutate(o_reviewed = Map(\(x, y, z) append(x, list(
row_id = y,
disabled = z,
updated = isolate(session$userData$update_checkboxes[[form]]))
),
o_reviewed,
dplyr::row_number(),
subject_id != r$subject_id))
})
mod_review_form_tbl_server("review_form_tbl", r, table_data, form, reactive(input$show_all), table_names)

mod_review_form_tbl_server("review_form_tbl", r, study_form_data, form, reactive(input$show_all), table_names)

scaling_data <- reactive({
cols <- c("item_scale", "use_unscaled_limits")
Expand Down Expand Up @@ -229,7 +231,7 @@ mod_study_forms_server <- function(

if(form %in% c("Vital signs", "Vitals adjusted")){
shiny::exportTestValues(
table_data = subset(table_data(), input$show_all | subject_id == r$subject_id),
table_data = subset(study_form_data(), input$show_all | subject_id == r$subject_id),
fig_data = fig_data()
)
}
Expand Down
2 changes: 1 addition & 1 deletion inst/golem-config.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
default:
golem_name: clinsight
golem_version: 0.1.1.9020
golem_version: 0.1.1.9021
app_prod: no
user_identification: test_user
study_data: !expr clinsight::clinsightful_data
Expand Down
6 changes: 3 additions & 3 deletions man/mod_review_form_tbl_server.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions tests/testthat/_snaps/app_feature_04.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
# A tibble: 2 x 11
o_reviewed subject_id event_name `Systolic blood pressure`
<list> <chr> <chr> <chr>
1 <named list [4]> 9600-002 Screening <b>99*</b> mmHg
2 <named list [4]> 9600-002 Visit 2 <b>99*</b> mmHg
1 <named list [5]> 9600-002 Screening <b>99*</b> mmHg
2 <named list [5]> 9600-002 Visit 2 <b>99*</b> mmHg
`Diastolic blood pressure` Pulse Resp
<chr> <chr> <chr>
1 <b>77*</b> mmHg <b>77*</b> beats/min <b>9*</b> breaths/min
Expand Down
Loading

0 comments on commit 2145018

Please sign in to comment.