2024-12-09 14:00:44 +01:00
# ns <- NS(id)
ui_elements <- list (
2025-01-15 16:21:38 +01:00
##############################################################################
#########
######### Home panel
#########
##############################################################################
" home" = bslib :: nav_panel (
title = " freesearcheR" ,
shiny :: markdown ( readLines ( " www/intro.md" ) ) ,
icon = shiny :: icon ( " home" )
) ,
2024-12-09 14:00:44 +01:00
##############################################################################
#########
######### Import panel
#########
##############################################################################
" import" = bslib :: nav_panel (
2024-12-13 13:37:19 +01:00
title = " Import" ,
2025-01-15 16:21:38 +01:00
shiny :: tagList (
shiny :: h4 ( " Choose your data source" ) ,
# shiny::conditionalPanel(
# condition = "output.has_input=='yes'",
# # Input: Select a file ----
# shiny::helpText("Analyses are performed on provided data")
# ),
# shiny::conditionalPanel(
# condition = "output.has_input=='no'",
# Input: Select a file ----
shinyWidgets :: radioGroupButtons (
inputId = " source" ,
selected = " env" ,
# label = "Choice: ",
choices = c (
" File upload" = " file" ,
" REDCap server" = " redcap" ,
" Local data" = " env"
2024-12-13 13:37:19 +01:00
) ,
2025-01-15 16:21:38 +01:00
# checkIcon = list(
# yes = icon("square-check"),
# no = icon("square")
# ),
width = " 100%"
) ,
shiny :: conditionalPanel (
condition = " input.source=='file'" ,
datamods :: import_file_ui ( " file_import" ,
title = " Choose a datafile to upload" ,
file_extensions = c ( " .csv" , " .txt" , " .xls" , " .xlsx" , " .rds" , " .fst" , " .sas7bdat" , " .sav" , " .ods" , " .dta" )
2024-12-13 13:37:19 +01:00
)
) ,
2025-01-15 16:21:38 +01:00
shiny :: conditionalPanel (
condition = " input.source=='redcap'" ,
m_redcap_readUI ( " redcap_import" )
) ,
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 :: br ( ) ,
shiny :: actionButton (
inputId = " act_start" ,
label = " Start" ,
width = " 100%" ,
icon = shiny :: icon ( " play" )
) ,
shiny :: helpText ( ' After importing, hit "Start" or navigate to the desired tab.' ) ,
shiny :: br ( ) ,
shiny :: br ( )
)
2024-12-13 13:37:19 +01:00
) ,
##############################################################################
#########
######### Data overview panel
#########
##############################################################################
2024-12-16 22:21:54 +01:00
" overview" =
2025-01-15 16:21:38 +01:00
# bslib::nav_panel_hidden(
2024-12-16 22:21:54 +01:00
bslib :: nav_panel (
# value = "overview",
2025-01-15 16:21:38 +01:00
title = " Data" ,
2024-12-16 22:21:54 +01:00
bslib :: navset_bar (
fillable = TRUE ,
bslib :: nav_panel (
2025-01-15 16:21:38 +01:00
title = " Summary & filter" ,
tags $ h3 ( " Data summary and filtering" ) ,
2024-12-16 22:21:54 +01:00
fluidRow (
2025-01-15 16:21:38 +01:00
shiny :: column (
width = 9 ,
shiny :: tags $ p (
" B e l o w i s a s h o r t s u m m a r y t a b l e o f t h e p r o v i d e d d a t a .
On the right hand side you have the option to create filters.
At the bottom you ' l l f i n d a r a w o v e r v i e w o f t h e o r i g i n a l v s t h e m o d i f i e d d a t a . " )
2024-12-16 22:21:54 +01:00
)
2025-01-15 16:21:38 +01:00
) ,
2024-12-16 22:21:54 +01:00
fluidRow (
# column(
# width = 3,
# shiny::uiOutput("filter_vars"),
# shiny::conditionalPanel(
# condition = "(typeof input.filter_vars !== 'undefined' && input.filter_vars.length > 0)",
# datamods::filter_data_ui("filtering", max_height = "500px")
# )
# ),
# column(
# width = 9,
# DT::DTOutput(outputId = "filtered_table"),
# tags$b("Code dplyr:"),
# verbatimTextOutput(outputId = "filtered_code")
# ),
shiny :: column (
2025-01-15 16:21:38 +01:00
width = 9 ,
toastui :: datagridOutput ( outputId = " tbl_overview" ) ,
# data_summary_ui(id = "data_summary"),
2024-12-16 22:21:54 +01:00
shiny :: tags $ b ( " Reproducible code:" ) ,
shiny :: verbatimTextOutput ( outputId = " filtered_code" )
) ,
shiny :: column (
2025-01-15 16:21:38 +01:00
width = 3 ,
IDEAFilter :: IDEAFilter_ui ( " data_filter" ) # ,
# shiny::actionButton("save_filter", "Apply the filter")
)
) ,
fluidRow (
column (
width = 6 ,
tags $ b ( " Original data:" ) ,
# verbatimTextOutput("original"),
verbatimTextOutput ( " original_str" )
) ,
column (
width = 6 ,
tags $ b ( " Modified data:" ) ,
# verbatimTextOutput("modified"),
verbatimTextOutput ( " modified_str" )
)
)
) ,
# bslib::nav_panel(
# title = "Overview",
# DT::DTOutput(outputId = "table")
# ),
bslib :: nav_panel (
title = " Modify" ,
tags $ h3 ( " Subset, rename and convert variables" ) ,
fluidRow (
shiny :: column (
width = 9 ,
shiny :: tags $ p ( " B e l o w , y o u c a n s u b s e t t h e d a t a ( b y n o t s e l e c t i n g t h e v a r i a b l e s t o e x c l u d e o n a p p l y i n g c h a n g e s ) , r e n a m e v a r i a b l e s , s e t n e w l a b e l s ( f o r n i c e r t a b l e s i n t h e a n a l y s i s r e p o r t ) a n d c h a n g e v a r i a b l e c l a s s e s .
Italic text can be edited / changed.
On the right , you can create and modify factor / categorical variables as well as resetting the data to the originally imported data. " )
)
) ,
fluidRow (
shiny :: column (
width = 9 ,
update_variables_ui ( " vars_update" )
) ,
shiny :: column (
width = 3 ,
shiny :: actionButton ( " modal_cut" , " Create factor variable" ) ,
shiny :: tags $ br ( ) ,
shiny :: helpText ( " Create factor/categorical variable from an other value." ) ,
2024-12-16 22:21:54 +01:00
shiny :: tags $ br ( ) ,
shiny :: tags $ br ( ) ,
shiny :: actionButton ( " modal_update" , " Reorder factor levels" ) ,
shiny :: tags $ br ( ) ,
2025-01-15 16:21:38 +01:00
shiny :: helpText ( " Reorder the levels of factor/categorical variables." ) ,
2024-12-16 22:21:54 +01:00
shiny :: tags $ br ( ) ,
2025-01-15 16:21:38 +01:00
shiny :: tags $ br ( ) ,
shiny :: actionButton ( " data_reset" , " Restore original data" ) ,
shiny :: tags $ br ( ) ,
shiny :: helpText ( " Reset to original imported dataset. Careful! There is no un-doing." ) ,
shiny :: tags $ br ( ) # ,
# shiny::tags$br(),
# shiny::tags$br(),
# IDEAFilter::IDEAFilter_ui("data_filter") # ,
2024-12-16 22:21:54 +01:00
# shiny::actionButton("save_filter", "Apply the filter")
)
2025-01-15 16:21:38 +01:00
# datamods::update_variables_ui("vars_update")
2024-12-13 13:37:19 +01:00
)
2025-01-15 16:21:38 +01:00
) ,
bslib :: nav_panel (
title = " Browser" ,
tags $ h3 ( " Browse the provided data" ) ,
shiny :: tags $ p (
" Below is a data table with all the modified data provided to browse and understand data."
) ,
shinyWidgets :: html_dependency_winbox ( ) ,
# fluidRow(
# column(
# width = 3,
# shiny::uiOutput("filter_vars"),
# shiny::conditionalPanel(
# condition = "(typeof input.filter_vars !== 'undefined' && input.filter_vars.length > 0)",
# datamods::filter_data_ui("filtering", max_height = "500px")
# )
# ),
# column(
# width = 9,
# DT::DTOutput(outputId = "filtered_table"),
# tags$b("Code dplyr:"),
# verbatimTextOutput(outputId = "filtered_code")
# ),
# shiny::column(
# width = 8,
toastui :: datagridOutput ( outputId = " table_mod" ) # ,
# shiny::tags$b("Reproducible code:"),
# shiny::verbatimTextOutput(outputId = "filtered_code")
# ),
# shiny::column(
# width = 4,
# shiny::actionButton("modal_cut", "Create factor from a variable"),
# shiny::tags$br(),
# shiny::tags$br(),
# shiny::actionButton("modal_update", "Reorder factor levels")#,
# # shiny::tags$br(),
# # shiny::tags$br(),
# # IDEAFilter::IDEAFilter_ui("data_filter") # ,
# # shiny::actionButton("save_filter", "Apply the filter")
# )
# )
2024-12-09 14:00:44 +01:00
)
2024-12-13 13:37:19 +01:00
2024-12-16 22:21:54 +01:00
# column(
# 8,
# shiny::verbatimTextOutput("filtered_code"),
# DT::DTOutput("filtered_table")
# ),
# column(4, IDEAFilter::IDEAFilter_ui("data_filter"))
)
) ,
2024-12-09 14:00:44 +01:00
##############################################################################
#########
######### Data analyses panel
#########
##############################################################################
2024-12-16 22:21:54 +01:00
" analyze" =
2025-01-15 16:21:38 +01:00
# bslib::nav_panel_hidden(
2024-12-16 22:21:54 +01:00
bslib :: nav_panel (
# value = "analyze",
title = " Analyses" ,
bslib :: navset_bar (
title = " " ,
# bslib::layout_sidebar(
# fillable = TRUE,
sidebar = bslib :: sidebar (
shiny :: helpText ( em ( " Please specify relevant settings for your data, and press 'Analyse'" ) ) ,
shiny :: uiOutput ( " outcome_var" ) ,
2025-01-15 16:21:38 +01:00
shiny :: radioButtons (
inputId = " all" ,
label = " Specify covariables" ,
inline = TRUE , selected = 2 ,
choiceNames = c (
" Yes" ,
" No"
) ,
choiceValues = c ( 1 , 2 )
) ,
shiny :: conditionalPanel (
condition = " input.all==1" ,
shiny :: uiOutput ( " include_vars" )
) ,
2024-12-16 22:21:54 +01:00
shiny :: uiOutput ( " strat_var" ) ,
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." )
) ,
2024-12-09 14:00:44 +01:00
shiny :: radioButtons (
2024-12-16 22:21:54 +01:00
inputId = " specify_factors" ,
label = " Specify categorical variables?" ,
2024-12-09 14:00:44 +01:00
selected = " no" ,
inline = TRUE ,
choices = list (
2024-12-16 22:21:54 +01:00
" Yes" = " yes" ,
" No" = " no"
2024-12-09 14:00:44 +01:00
)
) ,
2024-12-16 22:21:54 +01:00
shiny :: conditionalPanel (
condition = " input.specify_factors=='yes'" ,
shiny :: uiOutput ( " factor_vars" )
2024-12-09 14:00:44 +01:00
) ,
2024-12-16 22:21:54 +01:00
bslib :: input_task_button (
id = " load" ,
label = " Analyse" ,
icon = shiny :: icon ( " pencil" , lib = " glyphicon" ) ,
label_busy = " Working..." ,
icon_busy = fontawesome :: fa_i ( " arrows-rotate" ,
2025-01-15 16:21:38 +01:00
class = " fa-spin" ,
" aria-hidden" = " true"
2024-12-16 22:21:54 +01:00
) ,
2024-12-18 11:26:00 +01:00
type = " secondary" ,
2024-12-16 22:21:54 +01:00
auto_reset = TRUE
) ,
2024-12-18 11:26:00 +01:00
shiny :: helpText ( " If you change the parameters, press 'Analyse' again to update the tables" ) ,
# shiny::conditionalPanel(
# condition = "output.ready=='yes'",
2024-12-19 11:34:25 +01:00
shiny :: tags $ hr ( ) ,
shiny :: h4 ( " Download results" ) ,
shiny :: helpText ( " Choose your favourite output file format for further work, and download, when the analyses are done." ) ,
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" ,
2025-01-15 16:21:38 +01:00
label = " Download report" ,
2024-12-19 11:34:25 +01:00
icon = shiny :: icon ( " download" )
) ,
2025-01-15 16:21:38 +01:00
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 :: tags $ hr ( ) ,
shiny :: h4 ( " Download data" ) ,
shiny :: helpText ( " Choose your favourite output data format to download the modified data." ) ,
shiny :: selectInput (
inputId = " data_type" ,
label = " Data format" ,
selected = NULL ,
choices = list (
" R" = " rds" ,
" stata" = " dta"
)
) ,
shiny :: br ( ) ,
# Button
shiny :: downloadButton (
outputId = " data_modified" ,
label = " Download data" ,
icon = shiny :: icon ( " download" )
)
2024-12-13 13:37:19 +01:00
) ,
2024-12-16 22:21:54 +01:00
bslib :: nav_panel (
title = " Baseline characteristics" ,
gt :: gt_output ( outputId = " table1" )
2024-12-13 13:37:19 +01:00
) ,
2024-12-16 22:21:54 +01:00
bslib :: nav_panel (
title = " Regression table" ,
gt :: gt_output ( outputId = " table2" )
2024-12-13 13:37:19 +01:00
) ,
2024-12-16 22:21:54 +01:00
bslib :: nav_panel (
title = " Regression checks" ,
shiny :: plotOutput ( outputId = " check" )
)
2024-12-09 14:00:44 +01:00
)
2024-12-16 22:21:54 +01:00
) ,
2024-12-09 14:00:44 +01:00
##############################################################################
#########
######### Documentation panel
#########
##############################################################################
" docs" = bslib :: nav_panel (
2024-12-13 13:37:19 +01:00
title = " Documentation" ,
2024-12-17 11:30:17 +01:00
# shiny::tags$iframe("www/docs.html", height=600, width=535),
shiny :: htmlOutput ( " docs_file" ) ,
2024-12-09 14:00:44 +01:00
shiny :: br ( )
)
)
2024-12-18 10:37:37 +01:00
# Initial attempt at creating light and dark versions
light <- custom_theme ( )
2024-12-18 11:26:00 +01:00
dark <- custom_theme (
bg = " #000" ,
fg = " #fff"
)
2024-12-18 10:37:37 +01:00
# Fonts to consider:
# https://webdesignerdepot.com/17-open-source-fonts-youll-actually-love/
2025-01-15 16:21:38 +01:00
ui <- bslib :: page_fixed (
shiny :: tags $ style (
type = " text/css" ,
# add the name of the tab you want to use as title in data-value
shiny :: HTML (
" . c o n t a i n e r - f l u i d > . n a v > l i >
a [data - value = ' freesearcheR' ] { font - size : 28 px } "
)
) ,
2024-12-09 14:00:44 +01:00
title = " freesearcheR" ,
2024-12-18 10:37:37 +01:00
theme = light ,
shiny :: useBusyIndicators ( ) ,
2025-01-15 16:21:38 +01:00
bslib :: page_navbar (
# title = "freesearcheR",
2024-12-09 14:00:44 +01:00
id = " main_panel" ,
2024-12-19 11:34:25 +01:00
# header = shiny::tags$header(shiny::p("Data is only stored temporarily for analysis and deleted immediately afterwards.")),
2025-01-15 16:21:38 +01:00
ui_elements $ home ,
2024-12-09 14:00:44 +01:00
ui_elements $ import ,
2024-12-13 13:37:19 +01:00
ui_elements $ overview ,
2024-12-09 14:00:44 +01:00
ui_elements $ analyze ,
2024-12-19 11:34:25 +01:00
ui_elements $ docs ,
# bslib::nav_spacer(),
2024-12-19 21:21:29 +01:00
# bslib::nav_item(shinyWidgets::circleButton(inputId = "mode", icon = icon("moon"),status = "primary")),
2025-01-15 16:21:38 +01:00
fillable = FALSE ,
2024-12-19 11:34:25 +01:00
footer = shiny :: tags $ footer (
style = " background-color: #14131326; padding: 4px; text-align: center; bottom: 0; width: 100%;" ,
shiny :: p (
style = " margin: 1" ,
2025-01-15 16:21:38 +01:00
" Data is only stored for analyses and deleted immediately afterwards."
) ,
2024-12-19 11:34:25 +01:00
shiny :: p (
style = " margin: 1; color: #888;" ,
2025-01-15 16:21:38 +01:00
" Andreas G Damsbo | AGPLv3 license | " , shiny :: tags $ a ( " Source on Github" , href = " https://github.com/agdamsbo/freesearcheR/" , target = " _blank" , rel = " noopener noreferrer" )
2024-12-19 11:34:25 +01:00
) ,
)
2024-12-09 14:00:44 +01:00
)
)