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 (
2025-01-16 12:23:39 +01:00
" 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 .
2025-01-15 16:21:38 +01:00
On the right hand side you have the option to create filters.
2025-01-16 12:23:39 +01:00
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 ,
2025-01-16 11:24:26 +01:00
data_summary_ui ( id = " data_summary" )
2024-12-16 22:21:54 +01:00
) ,
shiny :: column (
2025-01-15 16:21:38 +01:00
width = 3 ,
2025-01-16 11:24:26 +01:00
IDEAFilter :: IDEAFilter_ui ( " data_filter" ) ,
shiny :: tags $ br ( ) ,
shiny :: tags $ b ( " Filter code:" ) ,
shiny :: verbatimTextOutput ( outputId = " filtered_code" ) ,
shiny :: tags $ br ( )
2025-01-15 16:21:38 +01:00
)
) ,
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 ,
2025-01-16 14:24:38 +01:00
update_variables_ui ( " vars_update" ) ,
shiny :: tags $ br ( )
2025-01-15 16:21:38 +01:00
) ,
shiny :: column (
width = 3 ,
2025-01-16 14:24:38 +01:00
tags $ h4 ( " Create new variables" ) ,
2025-01-16 11:24:26 +01:00
shiny :: tags $ br ( ) ,
2025-01-16 14:24:38 +01:00
shiny :: actionButton (
inputId = " modal_cut" ,
label = " Create factor variable" ,
width = " 100%"
) ,
2025-01-15 16:21:38 +01:00
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 ( ) ,
2025-01-16 14:24:38 +01:00
shiny :: actionButton (
inputId = " modal_update" ,
label = " Reorder factor levels" ,
width = " 100%"
) ,
2024-12-16 22:21:54 +01:00
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 ( ) ,
2025-01-16 14:24:38 +01:00
shiny :: actionButton (
inputId = " modal_column" ,
label = " New variable" ,
width = " 100%"
) ,
2025-01-16 11:24:26 +01:00
shiny :: tags $ br ( ) ,
shiny :: helpText ( " Create a new variable/column based on an R-expression." ) ,
shiny :: tags $ br ( ) ,
shiny :: tags $ br ( ) ,
2025-01-16 14:24:38 +01:00
tags $ h4 ( " Restore" ) ,
shiny :: actionButton (
inputId = " data_reset" ,
label = " Restore original data" ,
width = " 100%"
) ,
2025-01-15 16:21:38 +01:00
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 (
2025-01-16 12:23:39 +01:00
" Below is a data table with all the modified data provided to browse and understand data."
) ,
2025-01-15 16:21:38 +01:00
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" ,
2025-01-17 15:59:24 +01:00
id = " navanalyses" ,
2024-12-16 22:21:54 +01:00
bslib :: navset_bar (
title = " " ,
# bslib::layout_sidebar(
# fillable = TRUE,
sidebar = bslib :: sidebar (
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" )
) ,
2025-01-17 15:59:24 +01:00
bslib :: accordion (
open = " acc_chars" ,
multiple = FALSE ,
bslib :: accordion_panel (
value = " acc_chars" ,
title = " Characteristics" ,
icon = bsicons :: bs_icon ( " table" ) ,
shiny :: uiOutput ( " strat_var" ) ,
shiny :: helpText ( " Only factor/categorical variables are available for stratification. Go back to the 'Data' 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." )
2024-12-09 14:00:44 +01:00
)
) ,
2025-01-17 15:59:24 +01:00
bslib :: accordion_panel (
value = " acc_reg" ,
title = " Regression" ,
icon = bsicons :: bs_icon ( " calculator" ) ,
shiny :: uiOutput ( " outcome_var" ) ,
# shiny::selectInput(
# inputId = "design",
# label = "Study design",
# selected = "no",
# inline = TRUE,
# choices = list(
# "Cross-sectional" = "cross-sectional"
# )
# ),
shiny :: uiOutput ( " regression_type" ) ,
2025-01-20 11:27:54 +01:00
shiny :: radioButtons (
inputId = " add_regression_p" ,
label = " Add p-value" ,
inline = TRUE ,
selected = " no" ,
choices = list (
" Yes" = " yes" ,
" No" = " no"
)
) ,
2025-01-17 15:59:24 +01:00
bslib :: input_task_button (
id = " load" ,
label = " Analyse" ,
# icon = shiny::icon("pencil", lib = "glyphicon"),
icon = bsicons :: bs_icon ( " pencil" ) ,
label_busy = " Working..." ,
icon_busy = fontawesome :: fa_i ( " arrows-rotate" ,
class = " fa-spin" ,
" aria-hidden" = " true"
) ,
type = " secondary" ,
auto_reset = TRUE
) ,
2025-01-20 11:27:54 +01:00
shiny :: helpText ( " If you change the parameters, press 'Analyse' again to update the regression analysis" )
2024-12-09 14:00:44 +01:00
) ,
2025-01-17 15:59:24 +01:00
bslib :: accordion_panel (
value = " acc_down" ,
title = " Download" ,
icon = bsicons :: bs_icon ( " download" ) ,
shiny :: h4 ( " Report" ) ,
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" ,
label = " Download report" ,
icon = shiny :: icon ( " download" )
2024-12-16 22:21:54 +01:00
) ,
2025-01-17 15:59:24 +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 ( " 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-16 22:21:54 +01:00
) ,
2025-01-17 15:59:24 +01:00
# shiny::helpText(em("Please specify relevant settings for your data, and press 'Analyse'")),
# shiny::radioButtons(
# inputId = "specify_factors",
# label = "Specify categorical variables?",
# selected = "no",
# inline = TRUE,
# choices = list(
# "Yes" = "yes",
# "No" = "no"
# )
# ),
# shiny::conditionalPanel(
# condition = "input.specify_factors=='yes'",
# shiny::uiOutput("factor_vars")
# ),
2024-12-18 11:26:00 +01:00
# shiny::conditionalPanel(
# condition = "output.ready=='yes'",
2025-01-17 15:59:24 +01:00
# shiny::tags$hr(),
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
#########
##############################################################################
2025-01-16 12:23:39 +01:00
" docs" = bslib :: nav_item (
# shiny::img(shiny::icon("book")),
shiny :: tags $ a (
2025-01-16 14:24:38 +01:00
href = " https://agdamsbo.github.io/freesearcheR/" ,
" Docs (external)" ,
target = " _blank" ,
rel = " noopener noreferrer"
)
2024-12-09 14:00:44 +01:00
)
2025-01-16 12:23:39 +01:00
# bslib::nav_panel(
# title = "Documentation",
# # shiny::tags$iframe("www/docs.html", height=600, width=535),
# shiny::htmlOutput("docs_file"),
# shiny::br()
# )
2024-12-09 14:00:44 +01:00
)
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 (
2025-01-16 14:24:38 +01:00
shiny :: tags $ head ( includeHTML ( ( " www/umami-app.html" ) ) ) ,
2025-01-15 16:21:38 +01:00
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 ,
2025-01-16 12:23:39 +01:00
bslib :: nav_spacer ( ) ,
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-20 10:18:17 +01:00
" AG Damsbo | v" , format ( Sys.Date ( ) , format = ' %y%m%d' ) , " | 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
)
)