From cbeaf302e2039618846b8e3274aae8e65c333cd8 Mon Sep 17 00:00:00 2001 From: Edouard Date: Wed, 26 Apr 2023 15:51:33 -0500 Subject: [PATCH] [doc] Finalise the very initial wireframe...https://github.com/unhcr-americas/surveyDesigner/issues/11 --- DESCRIPTION | 4 +- NAMESPACE | 2 + R/app_ui.R | 214 +++++++++++++++++++++++++++++++++++++++++++++-- R/theme.R | 110 ++++++++++++++++++++++++ README.md | 5 +- dev/03_deploy.R | 6 +- docs/index.html | 4 +- docs/pkgdown.yml | 2 +- 8 files changed, 331 insertions(+), 16 deletions(-) create mode 100755 R/theme.R diff --git a/DESCRIPTION b/DESCRIPTION index c27e51d..6a86596 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -10,6 +10,8 @@ License: MIT + file LICENSE Imports: config (>= 0.3.1), dplyr, + dashboardthemes, + shinydashboard, golem (>= 0.4.0), magrittr, purrr, @@ -28,4 +30,4 @@ Config/testthat/edition: 3 Encoding: UTF-8 Language: en-US LazyData: true -RoxygenNote: 7.2.3 +RoxygenNote: 7.2.3.9000 diff --git a/NAMESPACE b/NAMESPACE index b2d8b97..8764827 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -4,7 +4,9 @@ export("%>%") export(Referential) export(run_app) import(shiny) +import(shinydashboard) importFrom(R6,R6Class) +importFrom(dashboardthemes,shinyDashboardThemeDIY) importFrom(dplyr,contains) importFrom(dplyr,filter) importFrom(dplyr,select) diff --git a/R/app_ui.R b/R/app_ui.R index 24b39f4..954554d 100644 --- a/R/app_ui.R +++ b/R/app_ui.R @@ -3,16 +3,207 @@ #' @param request Internal parameter for `{shiny}`. #' DO NOT REMOVE. #' @import shiny +#' @import shinydashboard +#' +#' @return Front end of app +#' #' @noRd app_ui <- function(request) { + + tagList( # Leave this function for adding external resources golem_add_external_resources(), - # Your application UI logic - fluidPage( - h1("Survey Designer") - ) - ) + theme_dashboard(), + # List the first level UI elements here + dashboardPage( + dashboardHeader(title = "Survey Designer (wireframe)"), + dashboardSidebar( + sidebarMenu( + menuItem(" Define Context", tabName = "Context", icon = icon("location-dot")), + menuItem(" Configure Content", tabName = "Content", icon = icon("arrows-to-circle")), + menuItem(" Set up Collection", tabName = "Collection", icon = icon("list-check")), + menuItem(" Export Forms", tabName = "Forms", icon = icon("share-from-square")) + ) + ), + + dashboardBody( + tabItems( + # Context ##### + tabItem(tabName = "Context", + p("A context reflects the implementation of the referential within a specific country or operation."), + fluidRow( + tags$div(title="Interview", + selectInput("library", label = "Methodology" , + choices = list("Household Survey (Representative Stock)" = "household_survey", + "Flow Monitoring (People not aiming to establish residence)" = "flow_monitoring", + "Key Informant (Persons with knowledge)" = "key_informant", + "Beneficiary Monitoring (Participant to an assistance program)" = "beneficiary_monitoring"), + selected = "household_survey" ) ), + + tags$div(title="Select your country - this will pull up automatically the Case Load that should be covered based on your annual statistical report and implement the languages translation and geographic breakdown required for the country", + selectInput("context", + label = "Country, defining then required languages & geographic Pcodes", + choices = list("Panama" = "Panama", + "Colombia" = "Colombia", + "Ecuador" = "Ecuador" ), + selected = "Panama") ), + + tags$div(title="Population Group to cover", + checkboxGroupInput("population", + label = "Target Population", + choices = list("Refugees (REF) & Asylum seekers (ASY)"="RAS", + "Internally displaced persons (IDP)"="IDP", + "Other people in need of international protection (OIP)"="OIP", + "Stateless Persons (STA)"="STA", + "Others of concern to UNHCR (OOC)"="OOC", + "Returnee (RET)"="RET", + "Host community (HCT)"="HCT" ), + selected = "Panama") ), + tags$div(title="Required Disaggregation for Crosstabulation", + checkboxGroupInput("Disaggregation", + label = "Disaggregation", + choices = list("Age"="Gender", + "Gender"="Gender", + "Disability"="Disability", + "Site"="Site" ), + selected = "Age") ) + ), + + br(), + p(" Next let's configure the content!") + ), + + # Content ##### + tabItem(tabName = "Content", + + checkboxGroupInput("topic", + label = "Select the Topics and/or indicators to prioritise", + choiceNames = list( + list( + icon("gavel") , + "Rights" + ), + list( + icon("home"), + "Trajectory" + ), + list( + icon("thermometer-full"), + "Intention" + ), + list( + icon("check-circle"), + "Basic Needs" + ), + list( + icon("certificate"), + "Coping Capacity" + ), + list( + icon("users"), + "Well-Being" + ), + list( + icon("blind"), + "Victimisation" + ), + list( + icon("usd"), + "Livelihood" + ), + list( + icon("book"), + "Education" + ), + list( + icon("medkit"), + "Health-Nutrition" + ), + list( + icon("eye"), + "Accountability" + ), + list( + icon("info-circle"), + "Information" + )), + choiceValues = list("Rights" , + "Trajectory" , + "Intention" , + "Basic Needs" , + "Coping Capacity" , + "Well-Being" , + "Victimisation" , + "Livelihood" , + "Education" , + "Health-Nutrition" , + "Accountability", + "Information" )), + + + br(), + p("As a result of this stage, below is a documentation of your survey-based indicators annual plan") , + + + ), + + # Collection #### + tabItem(tabName = "Collection" , + + tags$div(title="Using multiple data collection mode in parallel can help minimizing + non-reponse and increase coverage.", + checkboxGroupInput("mode", + label = "What Data Collection Modes can be used for this annual cycle?" , + # choiceNames = list("Face-to-face CAPI" , + # "Phone-Interview CATI" , + # "Self-administered CAWI" ), + + choiceNames = list( + list( + icon("clipboard-question"), + "Face-to-face CAPI"="CAPI" + ), + list( + icon("phone-square") , + "Phone-Interview CATI"="CATI" + ), + list( + icon("wifi"), + "Self-administered CAWI"= "CAWI" + )), + + choiceValues = list("Face-to-face" , + "Phone-Interview" , + "Self-administered" ))), + tags$div(title="Define how many data collection waves you can manage within the year. + The more data collection wave the more indicators can be collected. ", + selectInput("wave", + label = "How many data collection waves for this annual cycle?", + choices = list("One Wave" = "One-wave", + "Two Waves" = "Two-waves", + "Three Waves" = "Three-waves", + "Four Waves" = "Four-waves" ), + selected = "Two-waves") ), + + br(), + p("As a result of this stage, below is an estimation of Interview lenght per questionnaire") + ), + + # Forms #### + tabItem(tabName = "Forms", + + p("Add the script to introduce the survey ") , + p("Eventually change module sequences ") , + br(), + p("The resulting XlsForms can either be adjusted manually or + pushed directly to UNHCR Kobo server. + You can download the files for each data collection wave ") + ) + ) #end items + ) # end body + ) # end page + ) # end tag } #' Add external Resources to the Application @@ -30,12 +221,21 @@ golem_add_external_resources <- function() { ) tags$head( - favicon(), + golem::activate_js(), + golem::favicon(), bundle_resources( path = app_sys("app/www"), app_title = "surveyDesigner" ) # Add here other external resources - # for example, you can add shinyalert::useShinyalert() + # If you have a custom.css in the inst/app/www + # Or for example, you can add shinyalert::useShinyalert() here + #tags$link(rel="stylesheet", type="text/css", href="www/custom.css") ) } + + + + + + diff --git a/R/theme.R b/R/theme.R new file mode 100755 index 0000000..ddb703e --- /dev/null +++ b/R/theme.R @@ -0,0 +1,110 @@ +#' theme_dashboard +#' +#' +#' @return nothing +#' +#' @importFrom dashboardthemes shinyDashboardThemeDIY +#' +#' @noRd +theme_dashboard <- function() { + primary <- "#0072BC" + accent <- "#18375F" + secondary <- "#FAEB00" + + dashboardthemes::shinyDashboardThemeDIY( + + #general + appFontFamily = "Lato" + ,appFontColor = "#696969" + ,primaryFontColor = "#696969" + ,infoFontColor = "#696969" + ,successFontColor = "#696969" + ,warningFontColor = "#696969" + ,dangerFontColor = "#696969" + ,bodyBackColor = "#F8F8F8" + + #header + ,logoBackColor = primary + ,headerButtonBackColor = primary + ,headerButtonIconColor = "white" + ,headerButtonBackColorHover = accent + ,headerButtonIconColorHover = "white" + ,headerBackColor = primary + ,headerBoxShadowColor = "#aaaaaa" + ,headerBoxShadowSize = "0px 0px 0px" + + #sidebar + ,sidebarBackColor = "#EDEDED" + + ,sidebarPadding = 0 + + ,sidebarMenuBackColor = "transparent" + ,sidebarMenuPadding = 0 + ,sidebarMenuBorderRadius = 0 + + ,sidebarShadowRadius = "0px 0px 0px" + ,sidebarShadowColor = "#aaaaaa" + + ,sidebarUserTextColor = "#696969" + + ,sidebarSearchBackColor = "rgb(55,72,80)" + ,sidebarSearchIconColor = "rgb(153,153,153)" + ,sidebarSearchBorderColor = "rgb(55,72,80)" + + ,sidebarTabTextColor = "#696969" + ,sidebarTabTextSize = 13 + ,sidebarTabBorderStyle = "none none none solid" + ,sidebarTabBorderColor = "transparent" + ,sidebarTabBorderWidth = 5 + ,sidebarTabBackColorSelected = "transparent" + ,sidebarTabTextColorSelected = primary + ,sidebarTabRadiusSelected = "0px 0px 0px 0px" + ,sidebarTabBackColorHover = "#EDEDED" + ,sidebarTabTextColorHover = accent + ,sidebarTabBorderStyleHover = "none none none solid" + ,sidebarTabBorderColorHover = secondary + ,sidebarTabBorderWidthHover = 5 + ,sidebarTabRadiusHover = "0px 0px 0px 0px" + + ### boxes + ,boxBackColor = "white" + ,boxBorderRadius = 5 + ,boxShadowSize = "0px 0px 0px" + ,boxShadowColor = paste0(primary,"30") + ,boxTitleSize = 16 + ,boxDefaultColor = "white" + ,boxPrimaryColor = "white" + ,boxInfoColor = "rgb(210,214,220)" + ,boxSuccessColor = "rgba(0,255,213,1)" + ,boxWarningColor = "rgb(244,156,104)" + ,boxDangerColor = "rgb(255,88,55)" + + ,tabBoxTabColor = "white" + ,tabBoxTabTextSize = 12 + ,tabBoxTabTextColor = "#696969" + ,tabBoxTabTextColorSelected = primary + ,tabBoxBackColor = "white" + ,tabBoxHighlightColor = primary + ,tabBoxBorderRadius = 0 + + ### inputs + ,buttonBackColor = "rgb(245,245,245)" + ,buttonTextColor = "rgb(0,0,0)" + ,buttonBorderColor = "rgb(200,200,200)" + ,buttonBorderRadius = 5 + ,buttonBackColorHover = "rgb(235,235,235)" + ,buttonTextColorHover = "rgb(100,100,100)" + ,buttonBorderColorHover = "rgb(200,200,200)" + ,textboxBackColor = "rgb(255,255,255)" + ,textboxBorderColor = "rgb(200,200,200)" + ,textboxBorderRadius = 5 + ,textboxBackColorSelect = "rgb(245,245,245)" + ,textboxBorderColorSelect = "rgb(200,200,200)" + + ### tables + ,tableBackColor = NA + ,tableBorderColor = NA + ,tableBorderTopSize = 1 + ,tableBorderRowSize = 1 + ) +} #theme diff --git a/README.md b/README.md index f770c22..c3faf0e 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ For the end-user, aka the Survey Coordinator at Operation level, the application 2. Ease the __contextualization process__ from the global referential to the actual implementation in each country (i.e translating and adjusting the labels as per the specific context) and facilitate the feedback loop so that if the same ad-hoc questions are used in multiple context, they can be considered for inclusion in the global referential - 3. Support the usage of [mixed-mode (CAPI/CATI?CAWI)](https://www.youtube.com/watch?v=qRmy2OAnyWc) and multiple data collection waves to collect the final dataset within an __annual survey data collection cycle__, all of this allowing both to promote survey integration and to maximize the financial resources invested in those activities + 3. Support the usage of [mixed-mode (CAPI/CATI/CAWI)](https://www.youtube.com/watch?v=qRmy2OAnyWc) and multiple data collection waves to collect the final dataset within an __annual survey data collection cycle__, all of this allowing both to promote survey integration and to maximize the financial resources invested in those activities Overall, this will contribute over time to the creation of [standardized survey-based indicators](https://egrisstats.org/resource/data-disaggregation-of-sdg-indicators-by-forced-displacement/) for comparative data analysis across countries and contexts. @@ -24,7 +24,8 @@ Read more on the rationale for this app in the [vignette](https://unhcr-americas ## Run the app -The app is still under development - the prototype is accessible here: https://rstudio.unhcr.org/Survey_Designer/ + +:warning: *surveyDesigner is currently under development...* :construction: - the prototype is accessible here: https://rstudio.unhcr.org/Survey_Designer/ To run it locally, use diff --git a/dev/03_deploy.R b/dev/03_deploy.R index 6905dae..8ac58c6 100644 --- a/dev/03_deploy.R +++ b/dev/03_deploy.R @@ -28,15 +28,15 @@ devtools::build() ## RStudio ---- ## If you want to deploy on RStudio related platforms golem::add_rstudioconnect_file() -golem::add_shinyappsio_file() -golem::add_shinyserver_file() +#golem::add_shinyappsio_file() +#golem::add_shinyserver_file() ## Docker ---- ## If you want to deploy via a generic Dockerfile golem::add_dockerfile_with_renv() ## If you want to deploy to ShinyProxy -golem::add_dockerfile_with_renv_shinyproxy() +#golem::add_dockerfile_with_renv_shinyproxy() # Deploy to Posit Connect or ShinyApps.io diff --git a/docs/index.html b/docs/index.html index 46903f3..cfe7609 100644 --- a/docs/index.html +++ b/docs/index.html @@ -83,14 +83,14 @@
  1. Enforce a questionnaire design process that starts from a selection of indicators that needs to be measured and pre-select automatically all the required standardized survey modules and questions in order to measure them. Not only this ensure that standards are actually used, but it will also minimize the risk of questionnaire design mistakes: “collect what you need, use what you collect

  2. Ease the contextualization process from the global referential to the actual implementation in each country (i.e translating and adjusting the labels as per the specific context) and facilitate the feedback loop so that if the same ad-hoc questions are used in multiple context, they can be considered for inclusion in the global referential

  3. -
  4. Support the usage of mixed-mode (CAPI/CATI?CAWI) and multiple data collection waves to collect the final dataset within an annual survey data collection cycle, all of this allowing both to promote survey integration and to maximize the financial resources invested in those activities

  5. +
  6. Support the usage of mixed-mode (CAPI/CATI/CAWI) and multiple data collection waves to collect the final dataset within an annual survey data collection cycle, all of this allowing both to promote survey integration and to maximize the financial resources invested in those activities

Overall, this will contribute over time to the creation of standardized survey-based indicators for comparative data analysis across countries and contexts.

Read more on the rationale for this app in the vignette or go through the wiki to go through the technical specifications

Run the app

-

The app is still under development - the prototype is accessible here: https://rstudio.unhcr.org/Survey_Designer/

+

⚠️ surveyDesigner is currently under development… 🚧 - the prototype is accessible here: https://rstudio.unhcr.org/Survey_Designer/

To run it locally, use

 # install.packages("remotes")
diff --git a/docs/pkgdown.yml b/docs/pkgdown.yml
index 8006c3e..7367ef5 100644
--- a/docs/pkgdown.yml
+++ b/docs/pkgdown.yml
@@ -4,5 +4,5 @@ pkgdown_sha: ~
 articles:
   class-r6-for-the-referential: class-r6-for-the-referential.html
   surveyDesigner: surveyDesigner.html
-last_built: 2023-04-26T17:55Z
+last_built: 2023-04-26T18:09Z