2025-07-04 10:10:51 +02:00
#' FreesearchR UI elements list
#'
#' @param selection specify element to output
#'
#' @returns Shinu UI elements
#' @export
#'
ui_elements <- function ( selection ) {
out <- list (
##############################################################################
#########
######### Home panel
#########
##############################################################################
" home" = bslib :: nav_panel (
title = " FreesearchR" ,
# title = shiny::div(htmltools::img(src="FreesearchR-logo-white-nobg-h80.png")),
icon = shiny :: icon ( " house" ) ,
shiny :: fluidRow (
2025-09-10 12:00:03 +02:00
# "The browser language is",
# textOutput("your_lang"),
# p(i18n$t("Hello")),
# shiny::uiOutput(outputId = "language_select"),
2025-07-04 10:10:51 +02:00
## On building the dev-version for shinyapps.io, the dev_banner() is redefined
## Default just output "NULL"
## This could probably be achieved more legantly, but this works.
dev_banner ( ) ,
shiny :: column ( width = 2 ) ,
shiny :: column (
width = 8 ,
2025-09-10 12:00:03 +02:00
shiny :: uiOutput ( outputId = " language_select" ) ,
htmlOutput ( " intro_text" )
# shiny::includeHTML(i18n$t("www/intro.html"))
# shiny::markdown(readLines(i18n$t("www/intro.md")))
) ,
shiny :: column ( width = 2 )
2025-07-04 10:10:51 +02:00
)
) ,
##############################################################################
#########
######### Import panel
#########
##############################################################################
" import" = bslib :: nav_panel (
2025-09-10 12:00:03 +02:00
title = i18n $ t ( " Get started" ) ,
2025-07-04 10:10:51 +02:00
icon = shiny :: icon ( " play" ) ,
value = " nav_import" ,
shiny :: fluidRow (
shiny :: column ( width = 2 ) ,
shiny :: column (
width = 8 ,
2025-09-10 12:00:03 +02:00
shiny :: h4 ( i18n $ t ( " Choose your data" ) ) ,
# shiny::br(),
2025-07-04 10:10:51 +02:00
# shiny::uiOutput(outputId = "source"),
2025-09-10 12:00:03 +02:00
# radioGroupButtons(
# inputId = "source",
# selected = "file",
# choices = c("File" = "file"),
# size = "lg"
# ),
shiny :: selectInput (
2025-07-04 10:10:51 +02:00
inputId = " source" ,
2025-09-10 12:00:03 +02:00
label = " " ,
2025-07-04 10:10:51 +02:00
selected = " file" ,
2025-09-10 12:00:03 +02:00
choices = " file" ,
width = " 100%"
2025-07-04 10:10:51 +02:00
) ,
2025-09-10 12:00:03 +02:00
# shiny::tags$script('document.querySelector("#source div").style.width = "100%"'),
## Update this to change depending on run locally or hosted
shiny :: helpText ( i18n $ t ( " Upload a file, get data directly from REDCap or use local or sample data." ) ) ,
2025-07-04 10:10:51 +02:00
shiny :: br ( ) ,
shiny :: br ( ) ,
shiny :: conditionalPanel (
condition = " input.source=='file'" ,
import_file_ui (
id = " file_import" ,
layout_params = " dropdown" ,
# title = "Choose a datafile to upload",
file_extensions = c ( " .csv" , " .tsv" , " .txt" , " .xls" , " .xlsx" , " .rds" , " .ods" , " .dta" )
)
) ,
shiny :: conditionalPanel (
condition = " input.source=='redcap'" ,
2025-09-10 12:00:03 +02:00
shiny :: uiOutput ( outputId = " redcap_warning" ) ,
# shinyWidgets::alert(
# id = "redcap-warning",
# status = "warning",
# shiny::tags$h2(i18n$t("Please be mindfull handling sensitive data")),
# shiny::HTML(i18n$t("<p>The <em><strong>FreesearchR</strong></em> app only stores data for analyses, but please only use with sensitive data when running locally. <a href='https://agdamsbo.github.io/FreesearchR/#run-locally-on-your-own-machine'>Read more here</a></p>")),
# dismissible = TRUE
# ),
2025-07-04 10:10:51 +02:00
m_redcap_readUI (
id = " redcap_import" ,
title = " "
)
) ,
shiny :: conditionalPanel (
condition = " input.source=='env'" ,
import_globalenv_ui ( id = " env" , title = NULL )
) ,
# shiny::conditionalPanel(
# condition = "input.source=='redcap'",
# DT::DTOutput(outputId = "redcap_prev")
# ),
shiny :: conditionalPanel (
condition = " output.data_loaded == true" ,
shiny :: br ( ) ,
shiny :: actionButton (
inputId = " modal_initial_view" ,
2025-09-10 12:00:03 +02:00
label = i18n $ t ( " Quick overview" ) ,
2025-07-04 10:10:51 +02:00
width = " 100%" ,
icon = shiny :: icon ( " binoculars" ) ,
disabled = FALSE
) ,
shiny :: br ( ) ,
shiny :: br ( ) ,
2025-09-10 12:00:03 +02:00
shiny :: h5 ( i18n $ t ( " Select variables for final import" ) ) ,
2025-07-04 10:10:51 +02:00
shiny :: fluidRow (
shiny :: column (
width = 6 ,
2025-09-10 12:00:03 +02:00
shiny :: p ( i18n $ t ( " Exclude incomplete variables:" ) ) ,
2025-07-04 10:10:51 +02:00
shiny :: br ( ) ,
shinyWidgets :: noUiSliderInput (
inputId = " complete_cutoff" ,
label = NULL ,
update_on = " end" ,
min = 0 ,
max = 100 ,
step = 5 ,
value = 30 ,
format = shinyWidgets :: wNumbFormat ( decimals = 0 ) ,
color = datamods ::: get_primary_color ( )
) ,
2025-09-10 14:56:43 +02:00
shiny :: helpText ( i18n $ t ( " At 0, only complete variables are included; at 100, all variables are included." ) ) ,
2025-07-04 10:10:51 +02:00
shiny :: br ( )
) ,
shiny :: column (
width = 6 ,
2025-09-10 12:00:03 +02:00
shiny :: p ( i18n $ t ( " Manual selection:" ) ) ,
2025-07-04 10:10:51 +02:00
shiny :: br ( ) ,
shiny :: uiOutput ( outputId = " import_var" ) ,
shiny :: br ( )
)
) ,
shiny :: uiOutput ( outputId = " data_info_import" , inline = TRUE ) ,
shiny :: br ( ) ,
shiny :: br ( ) ,
shiny :: actionButton (
inputId = " act_start" ,
2025-09-10 12:00:03 +02:00
label = i18n $ t ( " Let's begin!" ) ,
2025-07-04 10:10:51 +02:00
width = " 100%" ,
icon = shiny :: icon ( " play" ) ,
disabled = TRUE
) ,
shiny :: br ( ) ,
shiny :: br ( )
) ,
shiny :: column ( width = 2 )
) ,
shiny :: br ( ) ,
shiny :: br ( )
)
) ,
##############################################################################
#########
######### Data overview panel
#########
##############################################################################
" prepare" = bslib :: nav_menu (
2025-09-10 14:56:43 +02:00
title = i18n $ t ( " Prepare" ) ,
2025-07-04 10:10:51 +02:00
icon = shiny :: icon ( " pen-to-square" ) ,
value = " nav_prepare" ,
bslib :: nav_panel (
2025-09-10 12:00:03 +02:00
title = i18n $ t ( " Overview and filter" ) ,
2025-07-04 10:10:51 +02:00
icon = shiny :: icon ( " eye" ) ,
value = " nav_prepare_overview" ,
2025-09-10 12:00:03 +02:00
tags $ h3 ( i18n $ t ( " Overview and filtering" ) ) ,
2025-07-04 10:10:51 +02:00
fluidRow (
shiny :: column (
width = 9 ,
shiny :: uiOutput ( outputId = " data_info" , inline = TRUE ) ,
shiny :: tags $ p (
2025-09-10 12:00:03 +02:00
i18n $ t ( " Below you find a summary table for quick insigths, and on the right you can visualise data classes, browse data and apply different data filters." )
2025-07-04 10:10:51 +02:00
)
) ,
shiny :: column (
width = 3 ,
shiny :: actionButton (
inputId = " modal_visual_overview" ,
2025-09-10 12:00:03 +02:00
label = i18n $ t ( " Visual overview" ) ,
2025-07-04 10:10:51 +02:00
width = " 100%" ,
disabled = TRUE
) ,
shiny :: br ( ) ,
shiny :: br ( ) ,
shiny :: actionButton (
inputId = " modal_browse" ,
2025-09-10 12:00:03 +02:00
label = i18n $ t ( " Browse data" ) ,
2025-07-04 10:10:51 +02:00
width = " 100%" ,
disabled = TRUE
) ,
shiny :: br ( ) ,
shiny :: br ( )
)
) ,
fluidRow (
shiny :: column (
width = 9 ,
data_summary_ui ( id = " data_summary" ) ,
shiny :: br ( ) ,
shiny :: br ( ) ,
shiny :: br ( ) ,
shiny :: br ( ) ,
shiny :: br ( )
) ,
shiny :: column (
width = 3 ,
2025-09-10 12:00:03 +02:00
shiny :: tags $ h6 ( i18n $ t ( " Filter data types" ) ) ,
2025-07-04 10:10:51 +02:00
shiny :: uiOutput (
outputId = " column_filter"
) ,
2025-09-10 12:00:03 +02:00
## This needs to run in server for translation
2025-07-04 10:10:51 +02:00
shiny :: helpText ( " Read more on how " , tags $ a (
" data types" ,
href = " https://agdamsbo.github.io/FreesearchR/articles/data-types.html" ,
target = " _blank" ,
rel = " noopener noreferrer"
) , " are defined." ) ,
2025-09-10 12:00:03 +02:00
validation_ui ( " validation_var" ) ,
2025-07-04 10:10:51 +02:00
shiny :: br ( ) ,
shiny :: br ( ) ,
2025-09-10 12:00:03 +02:00
shiny :: tags $ h6 ( i18n $ t ( " Filter observations" ) ) ,
shiny :: tags $ p ( i18n $ t ( " Apply filter on observation" ) ) ,
2025-07-04 10:10:51 +02:00
IDEAFilter :: IDEAFilter_ui ( " data_filter" ) ,
2025-09-10 12:00:03 +02:00
validation_ui ( " validation_obs" ) ,
2025-07-04 10:10:51 +02:00
shiny :: br ( ) ,
shiny :: br ( )
)
) ,
shiny :: br ( ) ,
shiny :: br ( ) ,
shiny :: br ( )
) ,
bslib :: nav_panel (
2025-09-10 12:00:03 +02:00
title = i18n $ t ( " Edit and create data" ) ,
2025-07-04 10:10:51 +02:00
icon = shiny :: icon ( " file-pen" ) ,
2025-09-10 12:00:03 +02:00
tags $ h3 ( i18n $ t ( " Subset, rename and convert variables" ) ) ,
2025-07-04 10:10:51 +02:00
fluidRow (
shiny :: column (
width = 9 ,
shiny :: tags $ p (
2025-09-10 12:00:03 +02:00
i18n $ t ( " Below, are several options for simple data manipulation like update variables by renaming, creating new labels (for nicer tables in the report) and changing variable classes (numeric, factor/categorical etc.)." ) ,
i18n $ t ( " There are more advanced options to modify factor/categorical variables as well as create new factor from a continous variable or new variables with R code. At the bottom you can restore the original data." ) ,
i18n $ t ( " Please note that data modifications are applied before any filtering." )
2025-07-04 10:10:51 +02:00
)
)
) ,
update_variables_ui ( " modal_variables" ) ,
shiny :: tags $ br ( ) ,
shiny :: tags $ br ( ) ,
2025-09-10 12:00:03 +02:00
shiny :: tags $ h4 ( i18n $ t ( " Advanced data manipulation" ) ) ,
shiny :: tags $ p ( i18n $ t ( " Below options allow more advanced varaible manipulations." ) ) ,
2025-07-04 10:10:51 +02:00
shiny :: tags $ br ( ) ,
shiny :: tags $ br ( ) ,
shiny :: fluidRow (
shiny :: column (
width = 4 ,
shiny :: actionButton (
inputId = " modal_update" ,
2025-09-10 12:00:03 +02:00
label = i18n $ t ( " Reorder factor levels" ) ,
2025-07-04 10:10:51 +02:00
width = " 100%"
) ,
shiny :: tags $ br ( ) ,
2025-09-10 12:00:03 +02:00
shiny :: helpText ( i18n $ t ( " Reorder the levels of factor/categorical variables." ) ) ,
2025-07-04 10:10:51 +02:00
shiny :: tags $ br ( ) ,
shiny :: tags $ br ( )
) ,
shiny :: column (
width = 4 ,
shiny :: actionButton (
inputId = " modal_cut" ,
2025-09-10 12:00:03 +02:00
label = i18n $ t ( " New factor" ) ,
2025-07-04 10:10:51 +02:00
width = " 100%"
) ,
shiny :: tags $ br ( ) ,
2025-09-10 12:00:03 +02:00
shiny :: helpText ( i18n $ t ( " Create factor/categorical variable from a continous variable (number/date/time)." ) ) ,
2025-07-04 10:10:51 +02:00
shiny :: tags $ br ( ) ,
shiny :: tags $ br ( )
) ,
shiny :: column (
width = 4 ,
shiny :: actionButton (
inputId = " modal_column" ,
2025-09-10 12:00:03 +02:00
label = i18n $ t ( " New variable" ) ,
2025-07-04 10:10:51 +02:00
width = " 100%"
) ,
shiny :: tags $ br ( ) ,
2025-09-10 12:00:03 +02:00
shiny :: helpText ( i18n $ t ( " Create a new variable based on an R-expression." ) ) ,
2025-07-04 10:10:51 +02:00
shiny :: tags $ br ( ) ,
shiny :: tags $ br ( )
)
) ,
2025-09-10 12:00:03 +02:00
tags $ h4 ( i18n $ t ( " Compare modified data to original" ) ) ,
2025-07-04 10:10:51 +02:00
shiny :: tags $ br ( ) ,
shiny :: tags $ p (
2025-09-10 12:00:03 +02:00
i18n $ t ( " Raw print of the original vs the modified data." )
2025-07-04 10:10:51 +02:00
) ,
shiny :: tags $ br ( ) ,
shiny :: fluidRow (
shiny :: column (
width = 6 ,
2025-09-10 12:00:03 +02:00
shiny :: tags $ b ( i18n $ t ( " Original data:" ) ) ,
2025-07-04 10:10:51 +02:00
shiny :: verbatimTextOutput ( " original_str" )
) ,
shiny :: column (
width = 6 ,
2025-09-10 12:00:03 +02:00
shiny :: tags $ b ( i18n $ t ( " Modified data:" ) ) ,
2025-07-04 10:10:51 +02:00
shiny :: verbatimTextOutput ( " modified_str" )
)
) ,
shiny :: tags $ br ( ) ,
shiny :: actionButton (
inputId = " data_reset" ,
label = " Restore original data" ,
width = " 100%"
) ,
shiny :: tags $ br ( ) ,
shiny :: helpText ( " Reset to original imported dataset. Careful! There is no un-doing." ) ,
shiny :: tags $ br ( )
)
# )
) ,
##############################################################################
#########
######### Descriptive analyses panel
#########
##############################################################################
" describe" =
bslib :: nav_menu (
2025-09-10 14:56:43 +02:00
title = i18n $ t ( " Evaluate" ) ,
2025-07-04 10:10:51 +02:00
icon = shiny :: icon ( " magnifying-glass-chart" ) ,
value = " nav_describe" ,
# id = "navdescribe",
# bslib::navset_bar(
# title = "",
bslib :: nav_panel (
title = " Characteristics" ,
icon = bsicons :: bs_icon ( " table" ) ,
bslib :: layout_sidebar (
sidebar = bslib :: sidebar (
shiny :: uiOutput ( outputId = " data_info_nochar" , inline = TRUE ) ,
bslib :: accordion (
open = " acc_chars" ,
multiple = FALSE ,
bslib :: accordion_panel (
open = TRUE ,
value = " acc_chars" ,
title = " Settings" ,
icon = bsicons :: bs_icon ( " table" ) ,
shiny :: uiOutput ( " strat_var" ) ,
shiny :: helpText ( " Only factor/categorical variables are available for stratification. Go back to the 'Prepare' tab to reclass a variable if it's not on the list." ) ,
shiny :: conditionalPanel (
condition = " input.strat_var!='none'" ,
shiny :: radioButtons (
inputId = " add_p" ,
label = " Compare strata?" ,
selected = " no" ,
inline = TRUE ,
choices = list (
" No" = " no" ,
" Yes" = " yes"
)
) ,
shiny :: helpText ( " Option to perform statistical comparisons between strata in baseline table." )
) ,
shiny :: br ( ) ,
shiny :: br ( ) ,
shiny :: actionButton (
inputId = " act_eval" ,
label = " Evaluate" ,
width = " 100%" ,
icon = shiny :: icon ( " calculator" ) ,
disabled = TRUE
)
)
)
) ,
gt :: gt_output ( outputId = " table1" )
)
) ,
bslib :: nav_panel (
title = " Correlations" ,
icon = bsicons :: bs_icon ( " bounding-box" ) ,
bslib :: layout_sidebar (
sidebar = bslib :: sidebar (
2025-07-22 20:16:47 +02:00
# shiny::uiOutput(outputId = "data_info_nochar", inline = TRUE),
2025-07-04 10:10:51 +02:00
bslib :: accordion (
open = " acc_chars" ,
multiple = FALSE ,
bslib :: accordion_panel (
value = " acc_cor" ,
title = " Correlations" ,
icon = bsicons :: bs_icon ( " bounding-box" ) ,
shiny :: uiOutput ( " outcome_var_cor" ) ,
shiny :: helpText ( " To avoid evaluating the correlation of the outcome variable, this can be excluded from the plot or select 'none'." ) ,
shiny :: br ( ) ,
shinyWidgets :: noUiSliderInput (
inputId = " cor_cutoff" ,
label = " Correlation cut-off" ,
min = 0 ,
max = 1 ,
step = .01 ,
value = .8 ,
format = shinyWidgets :: wNumbFormat ( decimals = 2 ) ,
color = datamods ::: get_primary_color ( )
) ,
shiny :: helpText ( " Set the cut-off for considered 'highly correlated'." )
)
)
) ,
data_correlations_ui ( id = " correlations" , height = 600 )
)
) ,
bslib :: nav_panel (
title = " Missings" ,
icon = bsicons :: bs_icon ( " x-circle" ) ,
bslib :: layout_sidebar (
sidebar = bslib :: sidebar (
bslib :: accordion (
open = " acc_chars" ,
multiple = FALSE ,
bslib :: accordion_panel (
vlaue = " acc_mis" ,
title = " Missings" ,
icon = bsicons :: bs_icon ( " x-circle" ) ,
shiny :: uiOutput ( " missings_var" ) ,
shiny :: helpText ( " To consider if data is missing by random, choose the outcome/dependent variable, if it has any missings to evaluate if there is a significant difference across other variables depending on missing data or not." )
)
)
) ,
data_missings_ui ( id = " missingness" )
)
)
) ,
##############################################################################
#########
2025-09-10 12:00:03 +02:00
######### Visuals panel
2025-07-04 10:10:51 +02:00
#########
##############################################################################
" visuals" = do.call (
bslib :: nav_panel ,
c (
list (
2025-09-10 14:56:43 +02:00
title = i18n $ t ( " Visuals" ) ,
2025-07-04 10:10:51 +02:00
icon = shiny :: icon ( " chart-line" ) ,
value = " nav_visuals"
) ,
data_visuals_ui ( " visuals" )
)
# do.call(
# bslib::navset_bar,
# data_visuals_ui("visuals")#,
# c(
# )
# )
) ,
##############################################################################
#########
######### Regression analyses panel
#########
##############################################################################
" analyze" =
bslib :: nav_panel (
2025-09-10 14:56:43 +02:00
title = i18n $ t ( " Regression" ) ,
2025-07-04 10:10:51 +02:00
icon = shiny :: icon ( " calculator" ) ,
value = " nav_analyses" ,
do.call (
bslib :: navset_card_tab ,
regression_ui ( " regression" )
)
) ,
##############################################################################
#########
######### Download panel
#########
##############################################################################
" download" =
bslib :: nav_panel (
2025-09-10 14:56:43 +02:00
title = i18n $ t ( " Download" ) ,
2025-07-04 10:10:51 +02:00
icon = shiny :: icon ( " download" ) ,
value = " nav_download" ,
shiny :: fluidRow (
shiny :: column ( width = 2 ) ,
shiny :: column (
width = 8 ,
2025-09-10 12:00:03 +02:00
shiny :: h4 ( i18n $ t ( " Analysis validation" ) ) ,
validation_ui ( " validation_all" ) ,
2025-07-04 10:10:51 +02:00
shiny :: fluidRow (
shiny :: column (
width = 6 ,
2025-09-10 12:00:03 +02:00
shiny :: h4 ( i18n $ t ( " Report" ) ) ,
shiny :: helpText ( i18n $ t ( " Choose your favourite output file format for further work, and download, when the analyses are done." ) ) ,
2025-07-04 10:10:51 +02:00
shiny :: br ( ) ,
shiny :: br ( ) ,
shiny :: selectInput (
inputId = " output_type" ,
label = " Output format" ,
selected = NULL ,
choices = list (
" MS Word" = " docx" ,
" LibreOffice" = " odt"
# ,
# "PDF" = "pdf",
# "All the above" = "all"
)
) ,
shiny :: br ( ) ,
# Button
shiny :: downloadButton (
outputId = " report" ,
label = " Download report" ,
icon = shiny :: icon ( " download" )
)
# shiny::helpText("If choosing to output to MS Word, please note, that when opening the document, two errors will pop-up. Choose to repair and choose not to update references. The issue is being worked on. You can always choose LibreOffice instead."),
) ,
shiny :: column (
width = 6 ,
shiny :: h4 ( " Data" ) ,
shiny :: helpText ( " Choose your favourite output data format to download the modified data." ) ,
shiny :: br ( ) ,
shiny :: br ( ) ,
shiny :: selectInput (
inputId = " data_type" ,
label = " Data format" ,
selected = NULL ,
choices = list (
" R" = " rds" ,
" stata" = " dta" ,
" CSV" = " csv"
)
) ,
shiny :: helpText ( " No metadata is saved when exporting to csv." ) ,
shiny :: br ( ) ,
shiny :: br ( ) ,
# Button
shiny :: downloadButton (
outputId = " data_modified" ,
label = " Download data" ,
icon = shiny :: icon ( " download" )
)
)
) ,
shiny :: br ( ) ,
shiny :: br ( ) ,
shiny :: h4 ( " Code snippets" ) ,
shiny :: tags $ p ( " Below are the code bits used to create the final data set and the main analyses." ) ,
shiny :: tags $ p ( " This can be used as a starting point for learning to code and for reproducibility." ) ,
shiny :: tagList (
lapply (
paste0 ( " code_" , c (
" import" , " format" , " data" , " variables" , " filter" , " table1" , " univariable" , " multivariable"
) ) ,
\ ( .x ) shiny :: htmlOutput ( outputId = .x )
)
) ,
shiny :: tags $ br ( ) ,
shiny :: br ( )
) ,
shiny :: column ( width = 2 )
)
) ,
##############################################################################
#########
######### Feedback link
#########
##############################################################################
" feedback" = bslib :: nav_item (
# shiny::img(shiny::icon("book")),
shiny :: tags $ a (
href = " https://redcap.au.dk/surveys/?s=JPCLPTXYDKFA8DA8" ,
" Feedback" , shiny :: icon ( " arrow-up-right-from-square" ) ,
target = " _blank" ,
rel = " noopener noreferrer"
)
) ,
##############################################################################
#########
######### Documentation link
#########
##############################################################################
" docs" = bslib :: nav_item (
# shiny::img(shiny::icon("book")),
shiny :: tags $ a (
href = " https://agdamsbo.github.io/FreesearchR/" ,
" Docs" , shiny :: icon ( " arrow-up-right-from-square" ) ,
target = " _blank" ,
rel = " noopener noreferrer"
)
)
# bslib::nav_panel(
# title = "Documentation",
# # shiny::tags$iframe("www/docs.html", height=600, width=535),
# shiny::htmlOutput("docs_file"),
# shiny::br()
# )
)
2025-09-10 12:00:03 +02:00
if ( ! is.null ( selection ) ) {
out [ [selection ] ]
} else {
out
2025-07-04 10:10:51 +02:00
}
2025-09-10 12:00:03 +02:00
}
2025-07-04 10:10:51 +02:00
# ls <- list("home"=1:4,
# "test"=1:4)
#