diff --git a/.RData b/.RData index f721097..339a670 100644 Binary files a/.RData and b/.RData differ diff --git a/NAMESPACE b/NAMESPACE index 5685e6f..b4cfbaa 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -57,7 +57,6 @@ importFrom(shinyAce,updateAceEditor) importFrom(shinyBS,bsCollapse) importFrom(shinyBS,bsCollapsePanel) importFrom(shinyBS,bsTooltip) -importFrom(shinyBS,tipify) importFrom(shinyBS,updateCollapse) importFrom(shinyFiles,getVolumes) importFrom(shinyFiles,parseDirPath) diff --git a/R/aboutUI-module.R b/R/aboutUI-module.R index cb400a5..c39e6d4 100644 --- a/R/aboutUI-module.R +++ b/R/aboutUI-module.R @@ -25,16 +25,16 @@ aboutUI <- function(id) { tags$p("The following people and parties have worked upstream of MetaShARK dev team to provide the fundamentals united in the present tool."), - uiOutput(ns("actors")), + uiOutput(NS(id, "actors")), # Informatics tags$h2("Computer material"), tags$p("The following references will lead the user to the source of tools and methods reused in MetaShARK."), - uiOutput(ns("informatics")), + uiOutput(NS(id, "informatics")), # Sci litt tags$h2("Literature"), tags$p("MetaShARK is based on the following papers and articles concerning mainly ecological metadata."), - uiOutput(ns("ecology")) + uiOutput(NS(id, "ecology")) ) } diff --git a/R/documentation-module.R b/R/documentation-module.R index 4d53e7b..a6f1bb1 100644 --- a/R/documentation-module.R +++ b/R/documentation-module.R @@ -21,7 +21,7 @@ docUI <- function(id) { 5, wellPanel( shinyTree::shinyTree( - outputId = ns("tree"), + outputId = NS(id, "tree"), search = TRUE, theme = "proton" ) @@ -32,7 +32,7 @@ docUI <- function(id) { 7, div( id = "docPanel", - uiOutput(ns("doc")) + uiOutput(NS(id, "doc")) ) ) ) diff --git a/R/eal_0.R b/R/eal_0.R deleted file mode 100644 index 3639af4..0000000 --- a/R/eal_0.R +++ /dev/null @@ -1,431 +0,0 @@ -#' @import shiny -#' @importFrom shinydashboard box -#' @importFrom shinycssloaders withSpinner -#' -#' @noRd -EMLALUI <- function(id, dev = FALSE) { - ns <- NS(id) - - fluidPage( - style = "padding-top:2.5%;", - shinydashboard::box( - title = span( - div("EML Assembly Line", style = "padding-right: 15px"), - uiOutput(ns("chain")), - style = "display: inline-flex" - ), - width = 12, - fluidRow( - uiOutput(ns("currentUI")) %>% - shinycssloaders::withSpinner(color = "#599cd4") - ) - ) # end variable UI - ) # end fluidPage -} - -#' @import shiny -#' @importFrom shinyBS tipify -#' -#' @noRd -EMLAL <- function(input, output, session, - save.variable, main.env) { - ns <- session$ns - .EAL <- main.env$EAL # local copy - - # NSB ----------------------------------------------------- - # names of EMLAL steps - steps <- c("SelectDP", "Data Files", "Attributes", "Categorical Variables", "Geographic Coverage", "Taxonomic Coverage", "Personnel", "Miscellaneous", "Make EML") - - NSB <- navSidebar("nav", main.env, save.variable) - assign("NSB", NSB, envir = main.env) - - # Output ----------------------------------------------------- - observeEvent(.EAL$navigate, { - # On loading DP, correct step - if(.EAL$navigate == -1) - .EAL$navigate <- match(utils::tail(save.variable$emlal$history,1), steps) - - if (.EAL$current[1] == "Data Files") { - unlink(main.env$PATHS$eal.tmp) - } - .EAL$current[1] <- steps[.EAL$navigate] - if (.EAL$current[1] == "Data Files" && - !dir.exists(main.env$PATHS$eal.tmp)) { - dir.create(main.env$PATHS$eal.tmp) - } - - if (isFALSE(.EAL$current[2])) { - .EAL$current[2] <- TRUE - } # trigger - .EAL$current[2] <- FALSE - NSB$tag.list <- tagList() - - # Edition changed path -> remove excedent history - if (!.EAL$current[1] %in% .EAL$history) { - .EAL$history <- c(.EAL$history, .EAL$current[1]) - } - - # Savevar modification - save.variable$emlal$step <- .EAL$navigate - save.variable$emlal$history <- .EAL$history - - # * Chain ----------------------------------------------------- - output$chain <- renderUI({ - validate( - need(.EAL$navigate > 1, "") - ) - - return( - tags$span( - tagList( - lapply(seq(.EAL$history)[-1], function(ind) { - .step.name <- .EAL$history[ind] - - if (.step.name != "Taxonomic Coverage") { - .style <- "color: dodgerblue;" - .description <- paste(.step.name, "(mandatory)") - } else { - .style <- "color: lightseagreen;" - .description <- paste(.step.name, "(facultative)") - } - - return( - actionLink( - ns(paste0("chain_", .step.name)), - "", - if (.step.name == .EAL$current[1]) { - icon("map-marker") - } else { - icon("circle") - }, - style = .style - ) %>% shinyBS::tipify( - title = .description - # , placement = "bottom" - # , trigger = "hover" - ) - ) # end of return - }), - paste0( - "Step ", .EAL$navigate, - "/", length(steps), - ": ", .EAL$current[1] - ) - ), - style = "position: right" - ) - ) - }) - - observe({ - validate( - need( - exists("main.env") && isTruthy(names(input)), - "Not initialized" - ), - need( - isTruthy(.EAL$history), - "No history available" - ), - need( - any(sapply( - .EAL$history, - grepl, - x = names(input) - ) %>% unlist()) && - length(.EAL$history) > 1, - "No history available" - ) - ) - - sapply(seq(.EAL$history)[-1], function(.ind) { - id <- paste0("chain_", .EAL$history[.ind]) - - observeEvent(input[[id]], { - req(input[[id]] && - .ind != .EAL$navigate) - .EAL$navigate <- .ind - NSB$NEXT <- NSB$NEXT + 1 - }) - }) - }) - - # * UI ----------------------------------------------------- - namespace <- .EAL$current[1] - - output$currentUI <- renderUI({ - .ui <- switch(.EAL$navigate, - SelectDPUI( - id = ns(namespace), - dev = main.env$DEV - ), - DataFilesUI( - id = ns(namespace), - dev = main.env$DEV - ), - AttributesUI( - id = ns(namespace), - dev = main.env$DEV - ), - CatVarsUI( - id = ns(namespace), - dev = main.env$DEV - ), - GeoCovUI( - id = ns(namespace), - dev = main.env$DEV - ), - TaxCovUI( - id = ns(namespace), - dev = main.env$DEV - ), - PersonnelUI( - id = ns(namespace), - dev = main.env$DEV - ), - MiscUI( - id = ns(namespace), - dev = main.env$DEV, - save.variable = isolate({savevar}) - ), - MakeEMLUI( - id = ns(namespace), - dev = main.env$DEV - ), - tags$h2("WIP") - ) - - return( - if (.EAL$navigate > 1) { - # NSB modifications - .nsb <- if (.EAL$current[1] == "Data Files") { - navSidebarUI(ns("nav"), .prev = FALSE) - } else if (.EAL$current[1] == "Make EML") { - navSidebarUI(ns("nav"), .next = FALSE) - } else { - navSidebarUI(ns("nav")) - } - - tagList( - column(10, .ui), - column(2, .nsb) - ) - } else { - tagList( - column(12, .ui) - ) - } - ) - }) - - # * Server ----------------------------------------------------- - save.variable <- switch(.EAL$navigate, - callModule( - SelectDP, namespace, - save.variable, main.env - ), - callModule( - DataFiles, namespace, - save.variable, main.env, - NSB = NSB - ), - callModule( - Attributes, namespace, - save.variable, main.env, - NSB = NSB - ), - callModule( - CatVars, namespace, - save.variable, main.env, - NSB = NSB - ), - callModule( - GeoCov, namespace, - save.variable, main.env, - NSB = NSB - ), - callModule( - TaxCov, namespace, - save.variable, main.env, - NSB = NSB - ), - callModule( - Personnel, namespace, - save.variable, main.env, - NSB = NSB - ), - callModule( - Misc, namespace, - save.variable, main.env, - NSB = NSB - ), - # TODO Add annotations here? - callModule( - MakeEML, namespace, - save.variable, main.env - ) - ) - # * Module helper ----------------------------------------------------- - NSB$help <- modalDialog( - title = paste0(.EAL$current[1], " - Help"), - switch(.EAL$navigate, - # SelectDP - tagList( - tags$p("This module allows you to manage your", tags$strong("data packages"), ". - A data package (aka DP) is a collection of a dataset and its associated metadata - and resources (scripts, literature, ...). You can:"), - tags$ul( - tags$li("Load an existing data package among local ones (left). You - will resume its edition at the last saved encountered step."), - tags$li( - "Create a new data package. You must fill in", tags$strong("three fields"), - tags$i("Data package name"), "will be used for identifying the DP,", - tags$i("Data package title"), "will be displayed when consulting the DP - page once formatted (explained in last step),", - tags$i("Data package license"), "is the license assigned to this production for - intellectual rights properties" - ) - ), - tags$p("Also, notice the", tags$strong("quick"), "check box above DP name. - Checking this box enables \"quick mode\" which will pre-fill most of the - fields in further steps. You still will be able to edit them at your - convenience.") - ), - # Data Files - tagList( - tags$p("This module allows you to load data files from the dataset you want to - describe. Once uploaded, you can set:"), - tags$ul( - tags$li(tags$i("Content name:"), "A name for the data contained in the file (e.g. table name)."), - tags$li(tags$i("URL:"), "If the file is accessible remotely, here is a way to reference it."), - tags$li(tags$i("Description:"), "A short text provided to describe the file, its content, - relevant information about the data in the entity.") - ), - tags$p("To edit your selection, select files among the list with the check boxes on - their left, then click the \"Remove\" button."), - tags$p("Recommended size per file is around 1 Gb. Such files and heavier ones might slow down the - app.") - ), - # Attributes - tagList( - tags$p("This module allows you to describe precisely each attribute of each file. Some of these metadata - are guessed from the data files. Such fields are annoted with a star (*). - For each attribute, you can set:"), - tags$ul( - tags$li(tags$i("Attribute Name*:"), "the name of the attribute."), - tags$li(tags$i("Attribute Description:"), "a "), - tags$li(tags$i("Attribute Class*:"), "the type of content in the attributes among - \"numeric\", \"character\", \"categorical\" and \"Date\". Categorical means a - character string with encoded values (e.g. Male/Female)."), - tags$li(tags$i("Date format (only for Date class): how the dates of the attributes are - written (e.g. DD-MM-YYYY).")), - tags$li(tags$i("Unit (only for Numeric class):"), "which is the unit used for the - numeric data of the attributes. The list is huge and refers to", tags$a("STMML Scientific - units", href = "http://www.ch.ic.ac.uk/rzepa/codata2/"), ". You can also define you own unit - (see Custom Units thereafter)."), - tags$li(tags$i("Missing Value Code:"), "a one-word code used instead of a missing value among - the data of the attribute currently described."), - tags$li(tags$i("Missing Value Code Explanation:"), "a short definition of the meaning(s) given - for the missing value code.") - ), - tags$h3("Custom units creation"), - tags$p("EML allows the user to define its own units, but this require to fulfill some more - fields. However, the custom units you will have defined will be saved into the Custom Units - table at the bottom of this page. You will find the written custom units in the units selection - once they are written. To define a custom unit, chose the unit to be \"custom\". A custom - unit is defined with:"), - tags$ul( - tags$li(tags$i("Unit id:"), "the id of the unit (e.g. gramsPerOneThirdMeter). The unit id - must validate the STMML schema."), - tags$li(tags$i("Unit type:"), "the physical property measured by the custom unit (e.g. mass)."), - tags$li(tags$i("Parent unit in SI:"), "from which unit among the most common one is the custom - unit derived (e.g. gram)."), - tags$li(tags$i("Multiplier to SI:"), "by how many has the custom unit to be multiplied to be - equal to its parent unit."), - tags$li(tags$i("Unit description:"), "some additional notes about the unit, how to compute it.") - ) - ), - # Catvars - tagList( - tags$p("This module allows you to detail the categorical variables (class \"categorical\" in Attributes). - For each variable, you will be able to detail each of its value by a short description.") - ), - # Geocov - tagList( - tags$p("This module allows you to define the geographic area in which the data have been produced. - You have the choice between two methods to define geographic coverage:"), - tags$ul( - tags$li( - tags$h4("Columns description (recommended)"), - tags$p("This method asks you to choose columns in one of your files. For latitude and longitude, - you can select either one or two columns. If a single column contains a pair of numbers, they - will be detected. Chosing single coordinates will be considered as single sites. Chosing pairs of - coordinates will be considered as sub-areas. For each coordinate, you can select a column - containing description for each one.") - ), - tags$li( - tags$h4("Custom description"), - tags$p("With this, you will be able to define by hand each one of the sites covered by your data.") - ) - ) - ), - # Taxcov - tagList( - tags$p("This module allows you to define the taxonomical coverage of the study. You will be asked to - select columns among your files containing the species name. Also, let the app know if the taxonomic - coverage shall be written with scientific, common or both names. At last, select at least one taxonomic - authority among the ones suggested."), - ), - # Personnel - tagList( - tags$p("This module allows you to get a full list of the people who contributed to the creation of - this dataset. The recommended best practice is to", tags$b("use the ORCID"), "of a person. With - this and the help of {rorcid}, the app will be able to fetch all available and interesting data. - You will be able to correct this afterwards. Also, note that you must fill in the fields - for two roles: creator and contact."), - tags$p("Suggested roles are the following:"), - tags$ul( - tags$li("Creator: person who contributed to produce the data."), - tags$li("Contact: persone to contact for any question about the data."), - tags$li("Principal investigator: person who led the creation of the dataset. Selecting this will allow - you to fill in additional information about the project and its funding."), - tags$li("Custom: as the list of roles is not exhaustive, feel free to add any role you consider important.") - ) - ), - # Misc - tagList( - tags$p("This module allows you to define the last details of your data package. Note that you can write - some of these metadata using the markdown syntax. Here are brief descriptions of the fields:"), - tags$ul( - tags$li("Abstract: the abstract of the publication linked to those data."), - tags$li("Methods: the methods used in the production of this dataset."), - tags$li( - "Keywords: you can type a list of keywords for your dataset. For each keyword, you can add a - keyword thesaurus, like", tags$a("the LTER controlled vocabulary ", href = "http://vocab.lternet.edu/vocab/vocab/index.php"), - ", which are controlled vocabulary your exact keyword originates from. Keywords thesaurus are not - required." - ), - tags$li("Temporal coverage: this lets you define the duration of the study during which the data have been produced."), - tags$li("Additional information: if any information has been omitted, you can provide it here (e.g. collection metadata - from GBIF-EML).") - ) - ), - # Make EML - tagList( - tags$p("Here we are (well done) ! This is the final step to write EML. Just click the button and let the magic happen. If an - error occurs, this will be displayed to the screen. In this case, do not hesitate to get in touch with the dev team."), - tags$p("You can also use the {emldown} package to get a human-readable version of the generated EML. The button below it will - let you download the result of this step.") - ) - ), - footer = modalButton("Close"), - easyClose = TRUE, fade = TRUE - ) - # * end ==== - }, - label = "EAL0 update" - ) - - # Save variable - return(save.variable) -} diff --git a/R/eal_0_functions.R b/R/eal_0_functions.R deleted file mode 100644 index 7ac9bb9..0000000 --- a/R/eal_0_functions.R +++ /dev/null @@ -1,317 +0,0 @@ -#' @title navSidebarUI -#' -#' @description UI part for shiny navigation sidebar module -#' -#' @param id shiny id -#' @param class css class style. Default is set to "navSidebar": -#' .navSidebar { -#' width: 100%; -#' text-align: center; -#' padding: 0; -#' } -#' @param .prev logical. Do you want a "Previous" actionButton? (prevTabButton) -#' @param .next logical. Do you want a "Next" actionButton? (nextTabButton) -#' @param ... UI tags set at the bottom of the navigation side bar -#' -#' @import shiny -navSidebarUI <- function(id, class = "navSidebar", - .prev = TRUE, .next = TRUE) { - ns <- NS(id) - - tags$div( - id = "navsidebar", - verticalLayout( - tags$h4("Navigation", class = "text-title"), - quitButton(id), - saveButton(id), - if (isTRUE(.prev)) prevTabButton(id) else NULL, - if (isTRUE(.next)) nextTabButton(id) else NULL, - uiOutput(ns("NSB_custom_ui")), - tags$hr(), - actionButton(ns("EAL_help"), "Help") - ), - class = class - ) -} - -#' @describeIn navSidebarUI -#' -#' @import shiny -quitButton <- function(id) { - ns <- NS(id) - - actionButton( - ns("quit"), - "Quit", - icon = icon("sign-out-alt"), - width = "100%" - ) -} - -#' @describeIn navSidebarUI -#' -#' @import shiny -saveButton <- function(id) { - ns <- NS(id) - - actionButton( - ns("save"), - "Save", - icon = icon("save", class = "regular"), - width = "100%" - ) -} - -#' @describeIn navSidebarUI -#' -#' @import shiny -nextTabButton <- function(id) { - ns <- NS(id) - - actionButton( - ns("nextTab"), - "Next", - icon = icon("arrow-right"), - width = "100%" - ) -} - -#' @describeIn navSidebarUI -#' -#' @import shiny -prevTabButton <- function(id) { - ns <- NS(id) - - actionButton( - ns("prevTab"), - "Previous", - icon = icon("arrow-left"), - width = "100%" - ) -} - -## Associated server functions ----------------------------------------------------- - -#' @title navSidebar -#' -#' @description server part for shiny navigation sidebar module (see [navSidebar()]). -#' The functions are very specific and thus are not exported. -#' -#' @param id shiny server id -#' @param main.env MetaShARK main.env variable -#' @param save.variable MetaShARK savevar variable -#' -#' @import shiny -navSidebar <- function(id, main.env, save.variable) { - NSB <- reactiveValues( - SAVE = 0, - NEXT = 0, - PREV = 0, - tag.list = tagList(), - help = modalDialog() - ) - - NSB <- callModule(onQuit, id, main.env, save.variable, NSB) - NSB <- callModule(onSave, id, save.variable, NSB) - NSB <- callModule(prevTab, id, main.env, NSB) - NSB <- callModule(nextTab, id, main.env, save.variable, NSB) - - # Custom on-the-fly server - callModule( - function(input, output, session, x = NSB) { - output$NSB_custom_ui <- renderUI({ - x$tag.list - }) - - observeEvent(input$EAL_help, { - showModal(x$help) - }) - }, - id - ) - - return(NSB) -} - -#' @describeIn navSidebar -#' -#' @import shiny -#' @importFrom shinyjs onclick disable enable -onQuit <- function(input, output, session, - main.env, save.variable, NSB) { - ns <- session$ns - - # modal dialog for quitting data description - quitModal <- modalDialog( - title = "You are leaving data description", - "Are you sure to leave? Some of your metadata have maybe not been saved.", - easyClose = FALSE, - footer = tagList( - actionButton(ns("cancel"), "Cancel"), - actionButton(ns("save_quit_button"), "Save & Quit"), - actionButton( - ns("quit_button"), - "Quit", - icon("times-circle"), - class = "redButton" - ) - ) - ) - - # show modal on 'quit' button clicked - observeEvent(input$quit, - { - endisableNSB(input, disable) - req(input$quit) - showModal(quitModal) - }, - label = "NSB quit" - ) - - # quits simply - observeEvent(input$cancel, - { - req(input$quit) - req(input$cancel) - endisableNSB(input, enable) - removeModal() - }, - label = "NSB cancel" - ) - - # calls saveRDS method and quits - observeEvent(input$save_quit_button, - { - req(input$quit) - req(input$save_quit_button) - endisableNSB(input, enable) - removeModal() - - NSB$tagList <- tagList() - NSB$SAVE <- NSB$SAVE + 1 - saveReactive(save.variable) - main.env$EAL$history <- "SelectDP" - main.env$EAL$navigate <- 1 - - file.remove( - list.files( - save.variable$emlal$SelectDP$dp.data.path, - pattern = "preview_" - ) - ) - }, - label = "NSB save+quit" - ) - - # quits simply - observeEvent(input$quit_button, - { - req(input$quit) - req(input$quit_button) - endisableNSB(input, enable) - removeModal() - - NSB$tag.list <- tagList() - main.env$EAL$history <- "SelectDP" - main.env$EAL$navigate <- 1 - - file.remove( - list.files( - save.variable$emlal$SelectDP$dp.data.path, - pattern = "preview___" - ) - ) - }, - label = "NSB +quit" - ) - - return(NSB) -} - -#' @describeIn navSidebar -#' -#' @import shiny -#' @importFrom shinyjs onclick disable enable -onSave <- function(input, output, session, save.variable, NSB) { - observeEvent(input$save, - { - req(input$save) - NSB$SAVE <- NSB$SAVE + 1 - }, - label = "NSB save" - ) - - return(NSB) -} - -#' @describeIn navSidebar -#' -#' @import shiny -#' @importFrom shinyjs onclick enable disable -nextTab <- function(input, output, session, - main.env, save.variable, NSB) { - - observe( - { - if (isFALSE(main.env$EAL$current[2])) { - disable("nextTab") - } else if (isTRUE(main.env$EAL$current[2])) { - enable("nextTab") - } - }, - label = "NSB cplt" - ) - - observeEvent(input$nextTab, - { - if(!isTRUE(main.env$EAL$current[2])) - showNotification( - "Check input information: some are not valid.", - type = "warning" - ) - req(isTRUE(main.env$EAL$current[2])) - endisableNSB(input, disable) - if (!main.env$EAL$current[1] %in% c("Geographic Coverage", "Taxonomic Coverage")) { - main.env$EAL$navigate <- main.env$EAL$navigate + 1 - NSB$tag.list <- tagList() - - # Savevar modification - save.variable$emlal$step <- main.env$EAL$navigate - } - NSB$NEXT <- NSB$NEXT + 1 - endisableNSB(input, enable) - }, - label = "NSB next" - ) - - return(NSB) -} -#' @describeIn navSidebar -#' -#' @import shiny -#' @importFrom shinyjs onclick enable disable -prevTab <- function(input, output, session, main.env, NSB) { - observeEvent(input$prevTab, - { - endisableNSB(input, disable) - main.env$EAL$navigate <- main.env$EAL$navigate - 1 - NSB$tag.list <- tagList() - NSB$PREV <- NSB$PREV + 1 - endisableNSB(input, enable) - }, - label = "NSB prev" - ) - - return(NSB) -} - -#' @importFrom shinyjs enable disable -#' -#' @noRd -endisableNSB <- function(input, todo) { - .n <- names(input) - .n <- .n[which(.n %in% c("save", "quit", "nextTab", "prevTab"))] - sapply(.n, function(ui, action = todo) { - action(ui) - }) -} \ No newline at end of file diff --git a/R/eal_1_SelectDP.R b/R/eal_1_SelectDP.R index 2b667c9..73ec954 100644 --- a/R/eal_1_SelectDP.R +++ b/R/eal_1_SelectDP.R @@ -2,16 +2,16 @@ #' @importFrom shinyFiles shinyDirButton #' #' @noRd -SelectDPUI <- function(id, width = 12, dev = FALSE) { +SelectDPUI <- function(id, main.env) { ns <- NS(id) - + # UI output return( fluidPage( title = "Organize data packages", fluidRow( collapsibleUI( - ns("usage"), + NS(id, "usage"), "TUTORIAL: EML Assembly Line workflow", ... = tagList( tags$p(tags$b("Welcome in the EML Assembly line."), "This tool is @@ -34,15 +34,15 @@ SelectDPUI <- function(id, width = 12, dev = FALSE) { filling. It will bring you to the next step."), tags$li(tags$b("Previous:"), "click this to come back to one of the previous steps. You can also use the steps", tags$span( - icon("circle"), - style = "color: dodgerblue;" - ), " markers to get + icon("circle"), + style = "color: dodgerblue;" + ), " markers to get to the desired step.") ) ) ) ), - # Data package location ----------------------------------------------------- + # Data package location ---- # if (!isTRUE(server)) { # tagList( # fluidRow( @@ -51,7 +51,7 @@ SelectDPUI <- function(id, width = 12, dev = FALSE) { # tags$b("Data Package will be saved in:") # } else { # shinyDirButton( - # ns("dp_location"), + # NS(id, "dp_location"), # "Choose directory", # "DP save location", # icon = icon("folder-open") @@ -59,7 +59,7 @@ SelectDPUI <- function(id, width = 12, dev = FALSE) { # } # ), # column(8, - # textOutput(ns("dp_location")), + # textOutput(NS(id, "dp_location")), # style = "text-align: left;" # ), # class = "inputBox" @@ -74,22 +74,20 @@ SelectDPUI <- function(id, width = 12, dev = FALSE) { hr(), # }, fluidRow( - # Load existing DP ----------------------------------------------------- - column( - ceiling(width / 2), + # Load existing DP ---- + column(6, tags$h4("Edit existing data package", style = "text-align:center" ), - uiOutput(ns("dp_list")) + uiOutput(NS(id, "dp_list")) ), - # Create DP ----------------------------------------------------- - column( - floor(width / 2), + # Create DP ---- + column(6, tags$h4("Create new data package", style = "text-align:center" ), checkboxInput( - ns("quick"), + NS(id, "quick"), tagList( tags$b("Quick mode"), "Most fields will be automatically filled" @@ -98,19 +96,19 @@ SelectDPUI <- function(id, width = 12, dev = FALSE) { ), # Data package title textInput( - ns("dp_name"), + NS(id, "dp_name"), "Data package name", placeholder = paste0(Sys.Date(), "_project") ), textInput( - ns("dp_title"), + NS(id, "dp_title"), "Dataset title", placeholder = "Any title is a title" ), tags$div( id = "license-help", selectInput( - ns("license"), + NS(id, "license"), "Select an Intellectual Rights License:", c("CCBY", "CC0"), multiple = FALSE @@ -121,7 +119,7 @@ SelectDPUI <- function(id, width = 12, dev = FALSE) { CC-BY-4.0: open source with authorship.
For more details, visit Creative Commons."), # DP creation - uiOutput(ns("dp_create")) + uiOutput(NS(id, "dp_create")) ) # end column2 ) # end fluidRow ) # end fluidPage @@ -135,51 +133,43 @@ SelectDPUI <- function(id, width = 12, dev = FALSE) { #' @importFrom jsonlite read_json unserializeJSON #' #' @noRd -SelectDP <- function(input, output, session, save.variable, main.env) { - ns <- session$ns - - if (main.env$dev) { - shinyjs::onclick("dev", +SelectDP <- function(id, main.env){ + moduleServer(id, function(input, output, session) { + save.variable <- main.env$save.variable + ns <- session$ns + + collapsible("usage") + + # variable initialization ---- + rv <- reactiveValues( + dp.location = main.env$PATHS$eal.dp, + dp.name = character(), + dp.title = character(), + dp.list = NULL, + dp.license = NULL + ) + + # DP location ---- + observeEvent(input$dp_location, { - req(main.env$EAL$navigate == 1) - browser() + req(input$dp_location) + rv$dp.location <- input$dp_location }, - asis = TRUE + label = "EAL1: input dp location" ) - } - - callModule(collapsible, "usage") - - # variable initialization ---- - rv <- reactiveValues( - dp.location = main.env$PATHS$eal.dp, - dp.name = character(), - dp.title = character(), - dp.list = NULL, - dp.license = NULL - ) - - # DP location ---- - observeEvent(input$dp_location, - { - req(input$dp_location) - rv$dp.location <- input$dp_location - }, - label = "EAL1: input dp location" - ) - - # Render selected DP location - output$dp_location <- renderText({ - rv$dp.location - }) - - # DP load ----------------------------------------------------- - # reset input if user comes back on this screen - # fetch list of DP at selected location - observeEvent({ - rv$dp.location - main.env$SETTINGS$logged - }, { + + # Render selected DP location + output$dp_location <- renderText({ + rv$dp.location + }) + + # DP load ---- + # reset input if user comes back on this screen + # fetch list of DP at selected location + observeEvent({ + rv$dp.location + main.env$SETTINGS$logged + }, { # Build full DP list .dp.path <- gsub( "/+", @@ -235,377 +225,371 @@ SelectDP <- function(input, output, session, save.variable, main.env) { else rv$dp.list <- NULL }, - label = "EAL1: build dp list" - ) - - # Render list of DP at selected location - output$dp_list <- renderUI({ - validate( - need( - isTruthy(rv$dp.list), - "No data package has been written." - ) + label = "EAL1: build dp list" ) - tagList( - radioButtons( - ns("dp_list"), - NULL, - choiceNames = c("None selected", rv$dp.list), - choiceValues = c("", rv$dp.list) - ), - actionButton( - ns("dp_load"), - "Load", - icon = icon("folder-open") - ), - actionButton( - ns("dp_delete"), - "Delete", - icon = icon("minus-circle"), - class = "redButton" - ), - downloadButton( - ns("dp_download"), - label = "Download .zip", - icon = icon("file-download") + + # Render list of DP at selected location + output$dp_list <- renderUI({ + validate( + need( + isTruthy(rv$dp.list), + "No data package has been written." + ) ) - ) - }) - - # Save updated index ---- - observeEvent(main.env$DP.LIST, { - data.table::fwrite( - main.env$DP.LIST, - isolate(main.env$PATHS$eal.dp.index), - sep = "\t" - ) - }) - - # Manage DP download ---- - output$dp_download <- downloadHandler( - filename = function() { - paste0(input$dp_list, "_emldp.zip") - }, - content = function(file) { - .path <- getwd() - setwd(main.env$PATHS$eal.dp) - utils::zip( - zipfile = file, - files = dir( - gsub( - "/+", - "/", - dir( - ".", - full.names = TRUE, - pattern = input$dp_list - ) - ), - recursive = TRUE, - full.names = TRUE + tagList( + radioButtons( + NS(id, "dp_list"), + NULL, + choiceNames = c("None selected", rv$dp.list), + choiceValues = c("", rv$dp.list) + ), + actionButton( + NS(id, "dp_load"), + "Load", + icon = icon("folder-open") + ), + actionButton( + NS(id, "dp_delete"), + "Delete", + icon = icon("minus-circle"), + class = "redButton" + ), + downloadButton( + NS(id, "dp_download"), + label = "Download .zip", + icon = icon("file-download") ) ) - setwd(.path) - }, - contentType = "application/zip" - ) - - # toggle Load and Delete buttons - observeEvent(input$dp_list, - { - if (input$dp_list != "") { - shinyjs::enable("dp_load") - shinyjs::enable("dp_delete") - shinyjs::enable("dp_download") - } - else { - shinyjs::disable("dp_load") - shinyjs::disable("dp_delete") - shinyjs::disable("dp_download") - } - }, - label = "EAL1: UX hs" - ) - - # DP create ----------------------------------------------------- - # check name input - rv$valid.name <- FALSE - output$dp_create <- renderUI({ - rv$valid.name <- FALSE - validate( - need( - nchar(input$dp_name) > 3, - "Please type a name with at least 3 characters." - ), - need( - grepl("^[[:alnum:]_-]+$", input$dp_name) - && nzchar(input$dp_name), - "Only authorized characters are alphanumeric, '_' (underscore) and '-' (hyphen)." - ), - need( - input$dp_name != "" - && !(input$dp_name %in% rv$dp.list), - "This name is already used: change either save directory or data package name." - ), - need( - input$dp_title != "" - && grepl("^[[:alnum:]\\ \\.,:_-]+$", input$dp_title), - "This title has invalid character: use alphanumerics, or one of: - ' ' '.' ',' ':' '_' '-' " - # \" \", \".\", \",\", \":\", \"_\" or \"-\"." + }) + + # Save updated index ---- + observeEvent(main.env$DP.LIST, { + data.table::fwrite( + main.env$DP.LIST, + isolate(main.env$PATHS$eal.dp.index), + sep = "\t" ) - ) - rv$valid.name <- TRUE - return(actionButton(ns("dp_create"), "Create")) - }) - - observeEvent(input$quick, - { - req(input$dp_name %in% c("", paste0(Sys.Date(), "_project"))) # Do not change a yet changed name - if (input$quick) { - updateTextInput(session, "dp_name", value = paste0(Sys.Date(), "_project")) - } else { - updateTextInput(session, "dp_name", placeholder = paste0(Sys.Date(), "_project")) - } - }, - label = "EAL1: quick" - ) - - observeEvent(input$dp_name, - { - rv$dp.name <- input$dp_name - }, - label = "EAL1: save dp name" - ) - - observeEvent(input$dp_title, - { - rv$dp.title <- input$dp_title - }, - label = "EAL1: save dp title" - ) - - # license choice - observeEvent(input$license, - { - rv$dp.license <- input$license - }, - label = "EAL1: save dp license" - ) - - # DP management - on clicks ----------------------------------------------------- - # * Create DP ----------------------------------------------------- - onclick("dp_create", { - req(input$dp_create) - req(input$dp_name) - req(rv$valid.name) - - # variable operation - legibility purpose - dp <- input$dp_name - path <- paste0(rv$dp.location, dp, "_emldp") - title <- input$dp_title - license <- rv$dp.license - - # verbose - withProgress( - { - # save in empty dedicated variable - save.variable$emlal <- initReactive("emlal", savevar, main.env$EAL) - save.variable$emlal$SelectDP$dp.name <- dp - save.variable$emlal$SelectDP$dp.path <- path - save.variable$emlal$SelectDP$dp.metadata.path <- paste(path, dp, "metadata_templates", sep = "/") - save.variable$emlal$SelectDP$dp.data.path <- paste(path, dp, "data_objects", sep = "/") - save.variable$emlal$SelectDP$dp.eml.path <- paste(path, dp, "eml", sep = "/") - save.variable$emlal$SelectDP$dp.title <- title - save.variable$emlal$quick <- input$quick - incProgress(0.2) - - dir.create(path, recursive = TRUE) - # add DP to index - main.env$DP.LIST <- rbind( - main.env$DP.LIST, - data.frame( - creator.orcid = main.env$SETTINGS$user, - name = dp, - title = title, - path = path, - stringsAsFactors = FALSE - ) - ) - incProgress(0.2) - - # EAL template import - try( - EMLassemblyline::template_directories( - save.variable$emlal$SelectDP$dp.path, - save.variable$emlal$SelectDP$dp.name + }) + + # Manage DP download ---- + output$dp_download <- downloadHandler( + filename = function() { + paste0(input$dp_list, "_emldp.zip") + }, + content = function(file) { + .path <- getwd() + setwd(main.env$PATHS$eal.dp) + utils::zip( + zipfile = file, + files = dir( + gsub( + "/+", + "/", + dir( + ".", + full.names = TRUE, + pattern = input$dp_list + ) + ), + recursive = TRUE, + full.names = TRUE ) ) - incProgress(0.2) - x <- try( - EMLassemblyline::template_core_metadata( - save.variable$emlal$SelectDP$dp.metadata.path, - license - ) + setwd(.path) + }, + contentType = "application/zip" + ) + + # toggle Load and Delete buttons + observeEvent(input$dp_list, + { + if (input$dp_list != "") { + shinyjs::enable("dp_load") + shinyjs::enable("dp_delete") + shinyjs::enable("dp_download") + } + else { + shinyjs::disable("dp_load") + shinyjs::disable("dp_delete") + shinyjs::disable("dp_download") + } + }, + label = "EAL1: UX hs" + ) + + # DP create ---- + # check name input + rv$valid.name <- FALSE + output$dp_create <- renderUI({ + rv$valid.name <- FALSE + validate( + need( + nchar(input$dp_name) > 3, + "Please type a name with at least 3 characters." + ), + need( + grepl("^[[:alnum:]_-]+$", input$dp_name) + && nzchar(input$dp_name), + "Only authorized characters are alphanumeric, '_' (underscore) and '-' (hyphen)." + ), + need( + input$dp_name != "" + && !(input$dp_name %in% rv$dp.list), + "This name is already used: change either save directory or data package name." + ), + need( + input$dp_title != "" + && grepl("^[[:alnum:]\\ \\.,:_-]+$", input$dp_title), + "This title has invalid character: use alphanumerics, or one of: + ' ' '.' ',' ':' '_' '-' " + # \" \", \".\", \",\", \":\", \"_\" or \"-\"." ) - incProgress(0.2) - - if (class(x) != "try-error") { - rv$dp.list <- c(rv$dp.list, dp) - main.env$EAL$navigate <- main.env$EAL$navigate + 1 - saveReactive(save.variable) - incProgress(0.2) + ) + rv$valid.name <- TRUE + return(actionButton(NS(id, "dp_create"), "Create")) + }) + + observeEvent(input$quick, + { + req(input$dp_name %in% c("", paste0(Sys.Date(), "_project"))) # Do not change a yet changed name + if (input$quick) { + updateTextInput(session, "dp_name", value = paste0(Sys.Date(), "_project")) } else { - unlink(path, recursive = TRUE) - save.variable <- initReactive(main.env = main.env$EAL) - incProgress(0.2) - showNotification(x, type = "error") + updateTextInput(session, "dp_name", placeholder = paste0(Sys.Date(), "_project")) } }, - message = paste("Creating:", path, "\n", sep = "") + label = "EAL1: quick" ) - }) - - # * Load DP ----------------------------------------------------- - shinyjs::onclick("dp_load", { - req(input$dp_list) - shinyjs::disable("dp_load") - # variable operation - legibility purpose - dp <- input$dp_list - path <- paste0(rv$dp.location, dp, "_emldp") - - # verbose - showNotification( - paste("Loading:", path, "\n", sep = ""), - type = "message" + + observeEvent(input$dp_name, + { + rv$dp.name <- input$dp_name + }, + label = "EAL1: save dp name" ) - - # actions - save.variable$emlal <- initReactive("emlal", savevar, main.env$EAL) - - .save.variable <- jsonlite::read_json(paste0(path, "/", dp, ".json"))[[1]] %>% - jsonlite::unserializeJSON() - save.variable$emlal <- setSavevar(.savevar$emlal, savevar$emlal) - - # Update paths from another file system - # * selectDP - sapply( - names(save.variable$emlal$SelectDP), - function(.dp.item){ - save.variable$emlal$SelectDP[[.dp.item]] <- gsub( - pattern=".*/dataPackagesOutput/emlAssemblyLine/", - replacement = rv$dp.location, - save.variable$emlal$SelectDP[[.dp.item]] - ) - } + + observeEvent(input$dp_title, + { + rv$dp.title <- input$dp_title + }, + label = "EAL1: save dp title" ) - # * datafiles - if(isTruthy(save.variable$emlal$DataFiles)){ - sapply(names(save.variable$emlal$DataFiles), function(col){ - save.variable$emlal$DataFiles[,col] <- gsub( - pattern=".*/dataPackagesOutput/emlAssemblyLine/", - replacement = rv$dp.location, - save.variable$emlal$DataFiles[,col] - ) - if(col == "size") - save.variable$emlal$DataFiles[,col] <- as.integer( - save.variable$emlal$DataFiles[,col] + + # license choice + observeEvent(input$license, + { + rv$dp.license <- input$license + }, + label = "EAL1: save dp license" + ) + + # DP management - on clicks ---- + # * Create DP ---- + onclick("dp_create", { + req(input$dp_create) + req(input$dp_name) + req(rv$valid.name) + + # variable operation - legibility purpose + dp <- input$dp_name + path <- paste0(rv$dp.location, dp, "_emldp") + title <- input$dp_title + license <- rv$dp.license + + # verbose + withProgress( + { + # save in empty dedicated variable + save.variable$emlal <- initReactive("emlal", savevar, main.env$EAL) + save.variable$emlal$SelectDP$dp.name <- dp + save.variable$emlal$SelectDP$dp.path <- path + save.variable$emlal$SelectDP$dp.metadata.path <- paste(path, dp, "metadata_templates", sep = "/") + save.variable$emlal$SelectDP$dp.data.path <- paste(path, dp, "data_objects", sep = "/") + save.variable$emlal$SelectDP$dp.eml.path <- paste(path, dp, "eml", sep = "/") + save.variable$emlal$SelectDP$dp.title <- title + save.variable$emlal$quick <- input$quick + incProgress(0.2) + + dir.create(path, recursive = TRUE) + # add DP to index + main.env$DP.LIST <- rbind( + main.env$DP.LIST, + data.frame( + creator.orcid = main.env$SETTINGS$user, + name = dp, + title = title, + path = path, + stringsAsFactors = FALSE + ) + ) + incProgress(0.2) + + # EAL template import + try( + EMLassemblyline::template_directories( + save.variable$emlal$SelectDP$dp.path, + save.variable$emlal$SelectDP$dp.name + ) ) - }) - } - # * misc - if(isTruthy(save.variable$emlal$Misc$abstract)){ - save.variable$emlal$Misc$abstract <- gsub( - ".*/dataPackagesOutput/emlAssemblyLine/", - rv$dp.location, - save.variable$emlal$Misc$abstract + incProgress(0.2) + x <- try( + EMLassemblyline::template_core_metadata( + save.variable$emlal$SelectDP$dp.metadata.path, + license + ) + ) + incProgress(0.2) + + if (class(x) != "try-error") { + rv$dp.list <- c(rv$dp.list, dp) + main.env$EAL$page <- main.env$EAL$page + 1 + saveReactive(save.variable) + incProgress(0.2) + } else { + unlink(path, recursive = TRUE) + save.variable <- initReactive(main.env = main.env$EAL) + incProgress(0.2) + showNotification(x, type = "error") + } + }, + message = paste("Creating:", path, "\n", sep = "") ) - save.variable$emlal$Misc$methods <- gsub( - ".*/dataPackagesOutput/emlAssemblyLine/", - rv$dp.location, - save.variable$emlal$Misc$methods + }) + + # * Load DP ---- + shinyjs::onclick("dp_load", { + req(input$dp_list) + shinyjs::disable("dp_load") + # variable operation - legibility purpose + dp <- input$dp_list + path <- paste0(rv$dp.location, dp, "_emldp") + + # verbose + showNotification( + paste("Loading:", path, "\n", sep = ""), + type = "message" ) - save.variable$emlal$Misc$additional.information <- gsub( - ".*/dataPackagesOutput/emlAssemblyLine/", - rv$dp.location, - save.variable$emlal$Misc$additional.information + + # actions + save.variable$emlal <- initReactive("emlal", savevar, main.env$EAL) + + .save.variable <- jsonlite::read_json(paste0(path, "/", dp, ".json"))[[1]] %>% + jsonlite::unserializeJSON() + save.variable$emlal <- setSavevar(.savevar$emlal, savevar$emlal) + + # Update paths from another file system + # * selectDP + sapply( + names(save.variable$emlal$SelectDP), + function(.dp.item){ + save.variable$emlal$SelectDP[[.dp.item]] <- gsub( + pattern=".*/dataPackagesOutput/emlAssemblyLine/", + replacement = rv$dp.location, + save.variable$emlal$SelectDP[[.dp.item]] + ) + } ) - } + # * datafiles + if(isTruthy(save.variable$emlal$DataFiles)){ + sapply(names(save.variable$emlal$DataFiles), function(col){ + save.variable$emlal$DataFiles[,col] <- gsub( + pattern=".*/dataPackagesOutput/emlAssemblyLine/", + replacement = rv$dp.location, + save.variable$emlal$DataFiles[,col] + ) + if(col == "size") + save.variable$emlal$DataFiles[,col] <- as.integer( + save.variable$emlal$DataFiles[,col] + ) + }) + } + # * misc + if(isTruthy(save.variable$emlal$Misc$abstract)){ + save.variable$emlal$Misc$abstract <- gsub( + ".*/dataPackagesOutput/emlAssemblyLine/", + rv$dp.location, + save.variable$emlal$Misc$abstract + ) + save.variable$emlal$Misc$methods <- gsub( + ".*/dataPackagesOutput/emlAssemblyLine/", + rv$dp.location, + save.variable$emlal$Misc$methods + ) + save.variable$emlal$Misc$additional.information <- gsub( + ".*/dataPackagesOutput/emlAssemblyLine/", + rv$dp.location, + save.variable$emlal$Misc$additional.information + ) + } + + # TODO remove this later : update history + save.variable$emlal$history <- sapply(savevar$emlal$history, function(h) { + switch(h, + create = "Select Data Package", + DataFiles = "Data Files", + attributes = "Attributes", + CustomUnits = NULL, + CatVars = "Categorical Variables", + GeoCov = "Geographic Coverage", + TaxCov = "Taxonomic Coverage", + h + ) + }) %>% unname() + save.variable$emlal$quick <- isTRUE(savevar$emlal$quick) + + # resume where max reached + main.env$EAL$page <- if(save.variable$emlal$step > 1) + -1 + else + main.env$EAL$page + 1 + main.env$EAL$history <- save.variable$emlal$history + shinyjs::enable("dp_load") + }) - # TODO remove this later : update history - save.variable$emlal$history <- sapply(savevar$emlal$history, function(h) { - switch(h, - create = "Select Data Package", - DataFiles = "Data Files", - attributes = "Attributes", - CustomUnits = NULL, - CatVars = "Categorical Variables", - GeoCov = "Geographic Coverage", - TaxCov = "Taxonomic Coverage", - h - ) - }) %>% unname() - save.variable$emlal$quick <- isTRUE(savevar$emlal$quick) + # * Delete DP ---- + shinyjs::onclick("dp_delete", { + req(input$dp_list) + + # variable operation - legibility purpose + dp <- input$dp_list + + # actions + showModal( + modalDialog( + title = "Delete data package?", + paste("Are you sure to delete", dp, "?"), + footer = tagList( + modalButton("No"), + actionButton( + NS(id, "delete_confirm"), "Yes", + class = "redButton" + ) + ) # end footer + ) # end modalDialog + ) # end showModal + }) - # resume where max reached - main.env$EAL$navigate <- if(save.variable$emlal$step > 1) - -1 - else - main.env$EAL$navigate + 1 - main.env$EAL$HISTORY <- save.variable$emlal$history - shinyjs::enable("dp_load") - }) - - # * Delete DP ----------------------------------------------------- - shinyjs::onclick("dp_delete", { - req(input$dp_list) - - # variable operation - legibility purpose - dp <- input$dp_list - - # actions - showModal( - modalDialog( - title = "Delete data package?", - paste("Are you sure to delete", dp, "?"), - footer = tagList( - modalButton("No"), - actionButton( - ns("delete_confirm"), "Yes", - class = "redButton" - ) - ) # end footer - ) # end modalDialog - ) # end showModal - }) - - # If deletion is confirmed - shinyjs::onclick("delete_confirm", { - # variable operation - legibility purpose - dp <- input$dp_list - if(grepl("\\(public\\)", dp)) - dp <- gsub(" \\(public\\)", "", dp) - path <- paste0(rv$dp.location, dp, "_emldp") - - # verbose - showNotification( - paste("Deleting:", path, "\n", sep = "") - ) # to replace by deleting DP - - # actions - unlink(path, recursive = TRUE) - rv$dp.list <- rv$dp.list[rv$dp.list != dp] - main.env$DP.LIST <- main.env$DP.LIST[main.env$DP.LIST$name != dp] - removeModal() + # If deletion is confirmed + shinyjs::onclick("delete_confirm", { + # variable operation - legibility purpose + dp <- input$dp_list + if(grepl("\\(public\\)", dp)) + dp <- gsub(" \\(public\\)", "", dp) + path <- paste0(rv$dp.location, dp, "_emldp") + + # verbose + showNotification( + paste("Deleting:", path, "\n", sep = "") + ) # to replace by deleting DP + + # actions + unlink(path, recursive = TRUE) + rv$dp.list <- rv$dp.list[rv$dp.list != dp] + main.env$DP.LIST <- main.env$DP.LIST[main.env$DP.LIST$name != dp] + removeModal() + }) + + # Output ---- + return(save.variable) }) - - # Output ----------------------------------------------------- - return(save.variable) } - -# @importFrom EML read_eml -# -# @noRd -# loadFromDP <- function(save.variable, file) { -# loaded.eml <- read_eml(file) -# } diff --git a/R/eal_2_DataFiles.R b/R/eal_2_DataFiles.R index 0bc6ead..d359c90 100644 --- a/R/eal_2_DataFiles.R +++ b/R/eal_2_DataFiles.R @@ -2,9 +2,9 @@ #' @importFrom shinyFiles shinyFilesButton #' #' @noRd -DataFilesUI <- function(id, dev = FALSE) { +DataFilesUI <- function(id, main.env) { ns <- NS(id) - + return( fluidPage( tags$b("Disclaimers:"), @@ -16,7 +16,7 @@ DataFilesUI <- function(id, dev = FALSE) { tags$div( tagList( fileInput( - ns("add_data_files"), + NS(id, "add_data_files"), "Select data file(s) from your dataset", buttonLabel = span("Load files", icon("plus-circle")), multiple = TRUE @@ -24,8 +24,8 @@ DataFilesUI <- function(id, dev = FALSE) { ), style = "display: inline-block; vertical-align: top;" ), - uiOutput(ns("data_files")), - actionButton(ns("remove_data_files"), "Remove", + uiOutput(NS(id, "data_files")), + actionButton(NS(id, "remove_data_files"), "Remove", icon = icon("minus-circle"), class = "redButton" ) @@ -39,292 +39,290 @@ DataFilesUI <- function(id, dev = FALSE) { #' @importFrom EMLassemblyline template_table_attributes #' #' @noRd -DataFiles <- function(input, output, session, save.variable, main.env, NSB) { - ns <- session$ns - if (main.env$DEV) { - shinyjs::onclick("dev", +DataFiles <- function(id, main.env) { + moduleServer(id, function(input, output, session){ + save.variable <- main.env$save.variable + ns <- session$ns + + # Variable initialization ---- + rv <- reactiveValues( + data.files = data.frame(stringsAsFactors = FALSE) + ) + + if (checkTruth(save.variable$emlal$DataFiles)) { # from create button in SelectDP + .ind <- which(file.exists(save.variable$emlal$DataFiles$datapath)) + .col <- which(names(save.variable$emlal$DataFiles) != "metadatapath") + rv$data.files <- save.variable$emlal$DataFiles[.ind, .col] + } + + # Data file upload ---- + # * Add data files ---- + observeEvent(input$add_data_files, { - req(main.env$EAL$navigate == 2) - browser() + # validity checks + req(input$add_data_files) + + # retrieve data files info + loaded.files <- input$add_data_files + + req(checkTruth(loaded.files)) + + # remove spaces + loaded.files$name <- gsub(" ", "_", loaded.files$name) + + # add URL, description and table name columns + loaded.files$url <- rep("", dim(loaded.files)[1]) + loaded.files$description <- rep("", dim(loaded.files)[1]) + loaded.files$table.name <- rep("", dim(loaded.files)[1]) + + # bind into input + if (isFALSE(checkTruth(rv$data.files) && all(dim(rv$data.files) > 0))) { + rv$data.files <- loaded.files + } else { + sapply(loaded.files$name, function(filename){ + if (fs::is_dir(filename)) { + showNotification( + paste(filename, "is a folder."), + type = "warning" + ) + } else + if (!filename %in% rv$data.files$name) { + rv$data.files <- unique(rbind( + rv$data.files, + loaded.files[loaded.files$name == filename, ] + )) + } + }) + } + + # copies on the server + withProgress( + { + file.copy( + rv$data.files$datapath, + paste0(main.env$PATHS$eal.tmp, rv$data.files$name) + ) + incProgress(0.8) + + rv$data.files$datapath <- paste0(main.env$PATHS$eal.tmp, rv$data.files$name) + incProgress(0.2) + }, + message = "Downloading data files" + ) }, - asis = TRUE + ignoreInit = TRUE, + label = "EAL2: add files" ) - } - - # Variable initialization ----------------------------------------------------- - rv <- reactiveValues( - data.files = data.frame(stringsAsFactors = FALSE) - ) - - if (checkTruth(save.variable$emlal$DataFiles)) { # from create button in SelectDP - .ind <- which(file.exists(save.variable$emlal$DataFiles$datapath)) - .col <- which(names(save.variable$emlal$DataFiles) != "metadatapath") - rv$data.files <- save.variable$emlal$DataFiles[.ind, .col] - } - - # Data file upload ----------------------------------------------------- - # * Add data files ----------------------------------------------------- - observeEvent(input$add_data_files, - { - # validity checks - req(input$add_data_files) - - # retrieve data files info - loaded.files <- input$add_data_files - - req(checkTruth(loaded.files)) - - # remove spaces - loaded.files$name <- gsub(" ", "_", loaded.files$name) - - # add URL, description and table name columns - loaded.files$url <- rep("", dim(loaded.files)[1]) - loaded.files$description <- rep("", dim(loaded.files)[1]) - loaded.files$table.name <- rep("", dim(loaded.files)[1]) - - # bind into input - if (isFALSE(checkTruth(rv$data.files) && all(dim(rv$data.files) > 0))) { - rv$data.files <- loaded.files - } else { - sapply(loaded.files$name, function(filename){ - if (fs::is_dir(filename)) { - showNotification( - paste(filename, "is a folder."), - type = "warning" - ) - } else - if (!filename %in% rv$data.files$name) { - rv$data.files <- unique(rbind( - rv$data.files, - loaded.files[loaded.files$name == filename, ] - )) - } - }) - } - - # copies on the server - withProgress( - { - file.copy( - rv$data.files$datapath, - paste0(main.env$PATHS$eal.tmp, rv$data.files$name) + + # * Remove data files ---- + observeEvent(input$remove_data_files, + { + # validity check + req(input$select_data_files) + + # actions + rv$data.files <- rv$data.files[ + !(rv$data.files$name %in% input$select_data_files), + ] + }, + label = "EAL2: remove files" + ) + + # Display data files ---- + # * UI ---- + observeEvent(rv$data.files, { + df <- isolate(rv$data.files) + + output$data_files <- renderUI({ + validate( + need( + !any(dim(df) == 0) && !is.null(df), + "Select files to describe." ) - incProgress(0.8) - - rv$data.files$datapath <- paste0(main.env$PATHS$eal.tmp, rv$data.files$name) - incProgress(0.2) - }, - message = "Downloading data files" - ) - }, - ignoreInit = TRUE, - label = "EAL2: add files" - ) - - # * Remove data files ----------------------------------------------------- - observeEvent(input$remove_data_files, - { - # validity check - req(input$select_data_files) - - # actions - rv$data.files <- rv$data.files[ - !(rv$data.files$name %in% input$select_data_files), - ] - }, - label = "EAL2: remove files" - ) - - # Display data files ----------------------------------------------------- - # * UI ---- - observeEvent(rv$data.files, { - df <- isolate(rv$data.files) - - output$data_files <- renderUI({ - validate( - need( - !any(dim(df) == 0) && !is.null(df), - "Select files to describe." ) - ) - - checkboxGroupInput(ns("select_data_files"), - "Select files to delete (all files here will be kept otherwise)", - choiceNames = lapply( - df$name, - function(label) { - # Variable initialization - id <- match(label, df$name) - xls.warning <- if (grepl("xlsx?$", label)) { - tags$div( - "Only the first sheet of Excel files will be read.", - style = "color: red" - ) - } else { - NULL - } - - # Output - collapsibleUI( - id = ns(id), - label = label, - hidden = FALSE, - class = "inputBox", - tagList( - fluidRow( - column( - 6, - textInput( - ns(paste0(id, "-dataName")), - "Data table name", - value = label - ) - ), - column( - 6, - URL_Input_UI( - ns(paste0(id, "-dataURL")), - label = "Data remote location" - ) + + checkboxGroupInput(NS(id, "select_data_files"), + "Select files to delete (all files here will be kept otherwise)", + choiceNames = lapply( + df$name, + function(label) { + # Variable initialization + id <- match(label, df$name) + xls.warning <- if (grepl("xlsx?$", label)) { + tags$div( + "Only the first sheet of Excel files will be read.", + style = "color: red" + ) + } else { + NULL + } + + # Output + collapsibleUI( + id = ns(id), + label = label, + hidden = FALSE, + class = "inputBox", + tagList( + fluidRow( + column( + 6, + textInput( + ns(paste0(id, "-dataName")), + "Data table name", + value = label + ) + ), + column( + 6, + URL_Input_UI( + ns(paste0(id, "-dataURL")), + label = "Data remote location" + ) + ), ), - ), - xls.warning, - fluidRow( - column( - 12, - textAreaInput( - ns(paste0(id, "-dataDesc")), - "Data Table Description", - value = paste("Content of", label), - width = "100%" + xls.warning, + fluidRow( + column( + 12, + textAreaInput( + ns(paste0(id, "-dataDesc")), + "Data Table Description", + value = paste("Content of", label), + width = "100%" + ) ) ) ) ) + } + ), + choiceValues = df$name + ) + }) + }) + + # * Server ---- + observeEvent(names(input), { + req( + any(grepl("dataName", names(input))) || + any(grepl("dataURL", names(input))) || + any(grepl("dataDesc", names(input))) + ) + sapply(rv$data.files$name, function(id) { + collapsible(id) + ind <- match(id, rv$data.files$name) + + # Data name + observeEvent(input[[paste0(ind, "-dataName")]], + { + isolate( + rv$data.files[ind, "table.name"] <- input[[paste0(ind, "-dataName")]] ) - } - ), - choiceValues = df$name + }, + ignoreInit = FALSE + ) + # Data URL + observeEvent(input[[paste0(ind, "-dataURL")]], + { + isolate( + rv$data.files[ind, "url"] <- URL_Input(paste0(ind, "-dataURL")) + ) + }, + ignoreInit = FALSE + ) + # Description + observeEvent(input[[paste0(ind, "-dataDesc")]], + { + isolate( + rv$data.files[ind, "description"] <- input[[paste0(ind, "-dataDesc")]] + ) + }, + ignoreInit = FALSE + ) + }) + }) + + # Warnings: data size + observeEvent(rv$data.files, { + req(checkTruth(rv$data.files)) + files.size <- if (checkTruth(rv$data.files$size)) { + sum(rv$data.files$size) + } else { + 0 + } + files.size.max <- main.env$VALUES$thresholds$files.size.max + + style <- if (files.size < 0.9 * files.size.max) { + "color: green;" + } else if (files.size >= 0.9 * files.size.max && files.size < files.size.max) { + "color: gold;" + } else { + "color: red" + } + + EAL$tag.list <- tagList( + "Files size:", + tags$p( + utils::object.size(files.size), + if (files.size >= files.size.max) { + paste("Max. recommended:", utils::object.size(files.size.max)) + } else { + NULL + }, + style = style + ) ) }) - }) - - # * Server ---- - observeEvent(names(input), { - req( - any(grepl("dataName", names(input))) || - any(grepl("dataURL", names(input))) || - any(grepl("dataDesc", names(input))) + + # Saves ---- + observe({ + main.env$EAL$completed <- checkTruth(rv$data.files) && + all(dim(rv$data.files) > 0) + }) + + # observeEvent(NSB$SAVE, + shinyjs::onclick( + "fill-wizard-save", + asis = TRUE, + add = TRUE, + { + req(main.env$EAL$current == "Data Files") + req(isTruthy(rv$data.files$name)) + + save.variable <- saveReactive( + save.variable = savevar, + rv = list(DataFiles = rv) + ) + }, + label = "Save_DataFiles", + ignoreInit = TRUE ) - sapply(rv$data.files$name, function(id) { - callModule(collapsible, id) - ind <- match(id, rv$data.files$name) - - # Data name - observeEvent(input[[paste0(ind, "-dataName")]], - { - isolate( - rv$data.files[ind, "table.name"] <- input[[paste0(ind, "-dataName")]] - ) - }, - ignoreInit = FALSE - ) - # Data URL - observeEvent(input[[paste0(ind, "-dataURL")]], - { - isolate( - rv$data.files[ind, "url"] <- callModule(URL_Input, paste0(ind, "-dataURL")) - ) - }, - ignoreInit = FALSE - ) - # Description - observeEvent(input[[paste0(ind, "-dataDesc")]], - { - isolate( - rv$data.files[ind, "description"] <- input[[paste0(ind, "-dataDesc")]] + + # Process files ---- + observeEvent(EAL$.next, + { + req(main.env$EAL$current == "Data Files") + # Save + save.variable <- saveReactive( + save.variable, + rv = list(DataFiles = rv) + ) + + # EMLAL templating function + try( + EMLassemblyline::template_table_attributes( + path = save.variable$emlal$SelectDP$dp.metadata.path, + data.path = save.variable$emlal$SelectDP$dp.data.path, + data.table = save.variable$emlal$DataFiles$name ) - }, - ignoreInit = FALSE - ) - }) - }) - - # Warnings: data size - observeEvent(rv$data.files, { - req(checkTruth(rv$data.files)) - files.size <- if (checkTruth(rv$data.files$size)) { - sum(rv$data.files$size) - } else { - 0 - } - files.size.max <- main.env$VALUES$thresholds$files.size.max - - style <- if (files.size < 0.9 * files.size.max) { - "color: green;" - } else if (files.size >= 0.9 * files.size.max && files.size < files.size.max) { - "color: gold;" - } else { - "color: red" - } - - NSB$tagList <- tagList( - "Files size:", - tags$p( - utils::object.size(files.size), - if (files.size >= files.size.max) { - paste("Max. recommended:", utils::object.size(files.size.max)) - } else { - NULL - }, - style = style - ) + ) + }, + priority = 1, + ignoreInit = TRUE ) + + # Output ---- + return(save.variable) }) - - # Saves ----------------------------------------------------- - observe({ - main.env$EAL$current[2] <- checkTruth(rv$data.files) && - all(dim(rv$data.files) > 0) - }) - - observeEvent(NSB$SAVE, - { - req(utils::tail(main.env$EAL$history, 1) == "Data Files") - req(isTruthy(rv$data.files$name)) - - save.variable <- saveReactive( - save.variable = savevar, - rv = list(DataFiles = rv) - ) - }, - label = "Save_DataFiles", - ignoreInit = TRUE - ) - - # Process files ---- - observeEvent(NSB$NEXT, - { - req(main.env$EAL$current[1] == "Data Files") - # Save - save.variable <- saveReactive( - save.variable, - rv = list(DataFiles = rv) - ) - - # EMLAL templating function - try( - EMLassemblyline::template_table_attributes( - path = save.variable$emlal$SelectDP$dp.metadata.path, - data.path = save.variable$emlal$SelectDP$dp.data.path, - data.table = save.variable$emlal$DataFiles$name - ) - ) - }, - priority = 1, - ignoreInit = TRUE - ) - - # Output ----------------------------------------------------- - return(save.variable) } diff --git a/R/eal_3_Attributes.R b/R/eal_3_Attributes.R index 6c7c675..4eed1e6 100644 --- a/R/eal_3_Attributes.R +++ b/R/eal_3_Attributes.R @@ -5,7 +5,7 @@ #' @import shiny #' #' @noRd -AttributesUI <- function(id, title, dev) { +AttributesUI <- function(id, main.env) { ns <- NS(id) return( @@ -21,21 +21,21 @@ AttributesUI <- function(id, title, dev) { column( 1, actionButton( - ns("file_prev"), + NS(id, "file_prev"), "", icon("chevron-left") ) ), column( 10, - uiOutput(ns("current_file"), + uiOutput(NS(id, "current_file"), inline = TRUE ) ), column( 1, actionButton( - ns("file_next"), + NS(id, "file_next"), "", icon("chevron-right") ) @@ -44,666 +44,659 @@ AttributesUI <- function(id, title, dev) { fluidRow( column( 12, - uiOutput(ns("edit_attributes")) %>% + uiOutput(NS(id, "edit_attributes")) %>% shinycssloaders::withSpinner(color = "#599cd4") ) ), # Custom Units tags$h4("Custom Units"), fluidRow( - tableOutput(ns("CUUI")) + tableOutput(NS(id, "CUUI")) ) ) # end fluidPage ) # end return } -#' @describeIn AttributesUI -#' -#' @description server part of the Attributes module. -#' #' @importFrom data.table fwrite #' @import shiny #' @importFrom shinyjs hide show enable disable onclick #' @importFrom EMLassemblyline template_categorical_variables template_geographic_coverage #' @importFrom shinyBS bsCollapse bsCollapsePanel updateCollapse -Attributes <- function(input, output, session, - save.variable, main.env, NSB){ - ns <- session$ns - - if (main.env$DEV) { -shinyjs::onclick("dev", - { - req(main.env$EAL$navigate == 3) - browser() - }, - asis = TRUE - ) - } - - if (main.env$DEV || isTRUE(save.variable$emlal$quick)) { - .fill <- function(rv = rv) { - lapply(seq(rv$tables), function(ind) { - .table <- rv$tables[[ind]] - sapply(colnames(.table), function(col) { - # Set values - if (col == "attributeDefinition") { - rv$tables[[ind]][[col]] <- paste("Description for", rv$tables[[ind]][["attributeName"]]) - } - if (col %in% c("missingValueCodeExplanation", "missingValueCode")) { - rv$tables[[ind]][[col]] <- rep("LoremIpsum", dim(.table)[1]) - } - if (col == "dateTimeFormatString") { - .dat.row <- which(rv$tables[[ind]]$class == "Date") - rv$tables[[ind]][[col]] <- rep("", dim(.table)[1]) - if(isTruthy(.dat.row)) - rv$tables[[ind]][.dat.row, col] <- rep(main.env$FORMATS$dates[3], length(.dat.row)) - } - if (col == "unit") { - .uni.row <- which(rv$tables[[ind]]$class == "numeric") - rv$tables[[ind]][[col]] <- rep("", dim(.table)[1]) - if(isTruthy(.uni.row)) - rv$tables[[ind]][.uni.row, col] <- rep(main.env$FORMATS$dates[2], length(.uni.row)) - } +#' +#' @noRd +Attributes <- function(id, main.env) { + moduleServer(id, function(input, output, session){ + save.variable <- main.env$save.variable + ns <- session$ns + + if (main.env$DEV || isTRUE(save.variable$emlal$quick)) { + .fill <- function(rv = rv) { + lapply(seq(rv$tables), function(ind) { + .table <- rv$tables[[ind]] + sapply(colnames(.table), function(col) { + # Set values + if (col == "attributeDefinition") { + rv$tables[[ind]][[col]] <- paste("Description for", rv$tables[[ind]][["attributeName"]]) + } + if (col %in% c("missingValueCodeExplanation", "missingValueCode")) { + rv$tables[[ind]][[col]] <- rep("LoremIpsum", dim(.table)[1]) + } + if (col == "dateTimeFormatString") { + .dat.row <- which(rv$tables[[ind]]$class == "Date") + rv$tables[[ind]][[col]] <- rep("", dim(.table)[1]) + if(isTruthy(.dat.row)) + rv$tables[[ind]][.dat.row, col] <- rep(main.env$FORMATS$dates[3], length(.dat.row)) + } + if (col == "unit") { + .uni.row <- which(rv$tables[[ind]]$class == "numeric") + rv$tables[[ind]][[col]] <- rep("", dim(.table)[1]) + if(isTruthy(.uni.row)) + rv$tables[[ind]][.uni.row, col] <- rep(main.env$FORMATS$dates[2], length(.uni.row)) + } + + # Update values + if (ind == rv$current.file) { + sapply(1:dim(rv$tables[[ind]])[1], function(item) { + inputId <- paste(ind, item, col, sep = "-") + if (inputId %in% names(input)) { + if (col %in% c("unit", "dateTimeFormatString")) { + updateSelectInput(session, inputId, selected = rv$tables[[ind]][item, col]) + } + if (col %in% c("attributeDefinition", "missingValueCode", "missingValueCodeExplanation")) { + updateTextAreaInput(session, inputId, value = rv$tables[[ind]][item, col]) + } + } + }) + } + }) # end of sapply - # Update values + # Update current table if (ind == rv$current.file) { - sapply(1:dim(rv$tables[[ind]])[1], function(item) { - inputId <- paste(ind, item, col, sep = "-") - if (inputId %in% names(input)) { - if (col %in% c("unit", "dateTimeFormatString")) { - updateSelectInput(session, inputId, selected = rv$tables[[ind]][item, col]) - } - if (col %in% c("attributeDefinition", "missingValueCode", "missingValueCodeExplanation")) { - updateTextAreaInput(session, inputId, value = rv$tables[[ind]][item, col]) - } - } - }) + rv$current.table <- rv$tables[[ind]] } - }) # end of sapply - - # Update current table - if (ind == rv$current.file) { - rv$current.table <- rv$tables[[ind]] - } - }) # end of lapply - return(rv) - } # end of .fill - } - - # variable initialization ----------------------------------------------------- - rv <- reactiveValues( - data.filepath = save.variable$emlal$DataFiles$datapath, - filepath = save.variable$emlal$DataFiles$metadatapath, - filenames = basename(save.variable$emlal$DataFiles$metadatapath), - current.file = 1, - tables = NULL, - current.table = NULL, - current.preview = NULL, - cu.table = data.frame(stringsAsFactors = FALSE), - cu.values = rep(NA, 5), - modal.on = FALSE, - unit.id = character(), - units.list = character(), - annotations = reactiveValues( - values = data.frame(stringsAsFactors = FALSE), - count = 0 + }) # end of lapply + return(rv) + } # end of .fill + } + + # variable initialization ---- + rv <- reactiveValues( + data.filepath = save.variable$emlal$DataFiles$datapath, + filepath = save.variable$emlal$DataFiles$metadatapath, + filenames = basename(save.variable$emlal$DataFiles$metadatapath), + current.file = 1, + tables = NULL, + current.table = NULL, + current.preview = NULL, + cu.table = data.frame(stringsAsFactors = FALSE), + cu.values = rep(NA, 5), + modal.on = FALSE, + unit.id = character(), + units.list = character(), + annotations = reactiveValues( + values = data.frame(stringsAsFactors = FALSE), + count = 0 + ) ) - ) - rv$tables <- lapply( - rv$filepath, readDataTable, - data.table = FALSE, stringsAsFactors = FALSE - ) - rv$current.table <- rv$tables[[rv$current.file]] - rv$cu.table <- readDataTable( - dir( - save.variable$emlal$SelectDP$dp.metadata.path, - pattern = "ustom", - full.names = TRUE - ), - stringsAsFactors = FALSE, - ) - rv$units.list <- main.env$FORMATS$units - if (checkTruth(save.variable$emlal$Attributes$annotations)) { - rv$annotations$values <- save.variable$emlal$Attributes$annotations - rv$annotations$count <- nrow(rv$annotations$values) - } - else { - rv$annotations$values <- data.frame( - id = character(), - element = character(), - context = character(), - subject = character(), - predicate_label = character(), - predicate_uri = character(), - object_label = character(), - object_uri = character(), - stringsAsFactors = FALSE + rv$tables <- lapply( + rv$filepath, readDataTable, + data.table = FALSE, stringsAsFactors = FALSE ) - } - - if (isTRUE(save.variable$emlal$quick)) { - rv <- .fill(rv) - } - - observe( - { - . <- rv$current.table # trigger - - .tmp <- unique(c( - unlist(lapply(seq_along(rv$tables), function(t) { - .tab <- if (t == rv$current.file) { - rv$current.table - } else { - rv$tables[[t]] - } - .tab$unit - })), - main.env$FORMATS$units - )) - rv$units.list <- .tmp[.tmp != ""] - }, - label = "EAL3: unit list" - ) - - # Reactive triggers - curt <- makeReactiveTrigger() - - # List of observers - obs <- reactiveValues() - - # Navigation buttons ----------------------------------------------------- - onclick("file_prev", { - req(rv$current.file > 1) - # Save - if (!is.null(rv$current.table)) { - rv$tables[[rv$current.file]] <- rv$current.table - } - # Change file - rv$current.file <- rv$current.file - 1 - }) - - onclick("file_next", { - req(rv$current.file < length(rv$filenames)) - # Save - if (!is.null(rv$current.table)) { - rv$tables[[rv$current.file]] <- rv$current.table + rv$current.table <- rv$tables[[rv$current.file]] + rv$cu.table <- readDataTable( + dir( + save.variable$emlal$SelectDP$dp.metadata.path, + pattern = "ustom", + full.names = TRUE + ), + stringsAsFactors = FALSE, + ) + rv$units.list <- main.env$FORMATS$units + if (checkTruth(save.variable$emlal$Attributes$annotations)) { + rv$annotations$values <- save.variable$emlal$Attributes$annotations + rv$annotations$count <- nrow(rv$annotations$values) } - # Change file - rv$current.file <- rv$current.file + 1 - }) - - # update table - observeEvent(rv$current.file, - { - req(rv$current.file > 0) - rv$current.table <- rv$tables[[rv$current.file]] - rv$current.table[is.na(rv$current.table)] <- "" - rv$current.preview <- readDataTable( - rv$data.filepath[rv$current.file], - stringsAsFactors = FALSE, - nrows = 5 + else { + rv$annotations$values <- data.frame( + id = character(), + element = character(), + context = character(), + subject = character(), + predicate_label = character(), + predicate_uri = character(), + object_label = character(), + object_uri = character(), + stringsAsFactors = FALSE ) - }, - priority = 1 - ) - - # display - output$current_file <- renderUI( - tags$div( - rv$filenames[rv$current.file], - class = "ellipsis", - style = paste0( - "display: inline-block; + } + + if (isTRUE(save.variable$emlal$quick)) { + rv <- .fill(rv) + } + + observe( + { + . <- rv$current.table # trigger + + .tmp <- unique(c( + unlist(lapply(seq_along(rv$tables), function(t) { + .tab <- if (t == rv$current.file) { + rv$current.table + } else { + rv$tables[[t]] + } + .tab$unit + })), + main.env$FORMATS$units + )) + rv$units.list <- .tmp[.tmp != ""] + }, + label = "EAL3: unit list" + ) + + # Reactive triggers + curt <- makeReactiveTrigger() + + # List of observers + obs <- reactiveValues() + + # Navigation buttons ---- + onclick("file_prev", { + req(rv$current.file > 1) + # Save + if (!is.null(rv$current.table)) { + rv$tables[[rv$current.file]] <- rv$current.table + } + # Change file + rv$current.file <- rv$current.file - 1 + }) + + onclick("file_next", { + req(rv$current.file < length(rv$filenames)) + # Save + if (!is.null(rv$current.table)) { + rv$tables[[rv$current.file]] <- rv$current.table + } + # Change file + rv$current.file <- rv$current.file + 1 + }) + + # update table + observeEvent(rv$current.file, + { + req(rv$current.file > 0) + rv$current.table <- rv$tables[[rv$current.file]] + rv$current.table[is.na(rv$current.table)] <- "" + rv$current.preview <- readDataTable( + rv$data.filepath[rv$current.file], + stringsAsFactors = FALSE, + nrows = 5 + ) + }, + priority = 1 + ) + + # display + output$current_file <- renderUI( + tags$div( + rv$filenames[rv$current.file], + class = "ellipsis", + style = paste0( + "display: inline-block; font-size:14pt; text-align:center; width:100%; background: linear-gradient(90deg, #3c8dbc ", - round(100 * rv$current.file / length(rv$filenames)), - "%, white ", - round(100 * rv$current.file / length(rv$filenames)), - "%);" + round(100 * rv$current.file / length(rv$filenames)), + "%, white ", + round(100 * rv$current.file / length(rv$filenames)), + "%);" + ) ) ) - ) - - # * UI ----------------------------------------------------- - observeEvent(rv$current.file, { - req(checkTruth(rv$current.table)) - .current.table <- isolate(rv$current.table) - output$edit_attributes <- renderUI({ - # validity check - validate( - need( - !identical(.current.table, data.frame()) && - isTruthy(.current.table), - "No valid attributes table." - ) - ) + # * UI ---- + observeEvent(rv$current.file, { + req(checkTruth(rv$current.table)) + .current.table <- isolate(rv$current.table) - ui <- do.call( - bsCollapse, - args = c( - lapply( - seq(dim(.current.table)[1]), # rows - fields = colnames(.current.table), - function(row.index, fields) { - # prepare variables - attribute.row <- .current.table[row.index, ] - - return( - bsCollapsePanel( - title = attribute.row[fields[1]], - tagList( - column( - 9, - # Input ==== - lapply(fields[-1], function(colname) { - # prepare var - saved.value <- .current.table[row.index, colname] - inputId <- paste( - isolate(rv$current.file), - row.index, - sep = "-" - ) - - # GUI - attributeInputUI( - ns(inputId), - colname, - saved.value, - main.env$FORMATS, - rv - ) - }) # end of lapply colname - ), - column( - 3, - # Preview ==== - h4("Preview:"), - tableOutput( - ns(paste0( - "preview-", - colnames(rv$current.preview)[row.index] - )) - ), - tags$hr(), - # Annotate ==== - # tags$div( - # annotateUI( - # ns(paste( - # "annotate", - # isolate(rv$current.file), - # row.index, - # sep = "-" - # )) - # ), - # class = "inputbox wip" - # ) - ) # end of column - ) - ) # end of bsCollapsePanel - ) # end of return - } - ), # end of lapply : row.index - id = ns("collapse") + output$edit_attributes <- renderUI({ + # validity check + validate( + need( + !identical(.current.table, data.frame()) && + isTruthy(.current.table), + "No valid attributes table." + ) ) - ) - return(ui) - }) - }) # end of observeEvent - - # * Server ----------------------------------------------------- - observeEvent(rv$current.file, { - req(checkTruth(rv$current.table)) - - sapply( - seq(dim(rv$current.table)[1]), - fields = colnames(rv$current.table)[-1], # not Attribute Name - function(row.index, fields) { - # TODO Update style: to correct - # updateCollapse( - # session = session, - # ns("collapse"), - # style = filled - # ) - - # Preview ==== - preview.column <- colnames(rv$current.preview)[row.index] - output[[paste0("preview-", preview.column)]] <- renderTable(rv$current.preview[[preview.column]]) - - # Annotate ==== - # annotateId <- paste( - # "annotate", - # isolate(rv$current.file), - # row.index, - # sep = "-" - # ) - # - # .tmp <- callModule( - # annotate, annotateId, - # save.variable, main.env, rv, row.index - # ) - - # Input ==== - lapply(fields, function(colname) { - inputId <- paste( - isolate(rv$current.file), - row.index, - sep = "-" - ) - - obs <- callModule( - attributeInput, - inputId, - rv, - row.index, - colname, - obs, - curt + ui <- do.call( + bsCollapse, + args = c( + lapply( + seq(dim(.current.table)[1]), # rows + fields = colnames(.current.table), + function(row.index, fields) { + # prepare variables + attribute.row <- .current.table[row.index, ] + + return( + bsCollapsePanel( + title = attribute.row[fields[1]], + tagList( + column( + 9, + # Input ==== + lapply(fields[-1], function(colname) { + # prepare var + saved.value <- .current.table[row.index, colname] + inputId <- paste( + isolate(rv$current.file), + row.index, + sep = "-" + ) + + # GUI + attributeInputUI( + ns(inputId), + colname, + saved.value, + main.env$FORMATS, + rv + ) + }) # end of lapply colname + ), + column( + 3, + # Preview ==== + h4("Preview:"), + tableOutput( + ns(paste0( + "preview-", + colnames(rv$current.preview)[row.index] + )) + ), + tags$hr(), + # Annotate ==== + # tags$div( + # annotateUI( + # ns(paste( + # "annotate", + # isolate(rv$current.file), + # row.index, + # sep = "-" + # )) + # ), + # class = "inputbox wip" + # ) + ) # end of column + ) + ) # end of bsCollapsePanel + ) # end of return + } + ), # end of lapply : row.index + id = NS(id, "collapse") ) - }) # end of lapply colname - } # end of *in situ* function - ) # end of sapply : row.index - }) # end of observeEvent - - # Custom units ---- - observe({ - curt$depend() - .current.table <- isolate(rv$current.table) - modal.on <- isolate(rv$modal.on) - req(any(.current.table$unit == "custom")) - - rv$unit.id <- c( - rv$current.file, - which(.current.table$unit == "custom"), - "unit" - ) - - row <- rv$unit.id[2] - class <- .current.table[row, "class"] + ) + return(ui) + }) + }) # end of observeEvent - if (class == "numeric" && - modal.on == FALSE) { - rv$cu.values <- rv$cu.table %>% - dplyr::filter(grepl(class, id)) - if (any(dim(rv$cu.values) == 0)) { - rv$cu.values <- rep(NA, 5) - } + # * Server ---- + observeEvent(rv$current.file, { + req(checkTruth(rv$current.table)) - showModal(CU_Modal(rv$cu.values, cu.table = rv$cu.table)) - - rv$modal.on <- TRUE - - isolate({ - rv$current.table[row, "unit"] <- "" - }) - } - }) - - CU_Modal <- function(values = rep(NA, 5), cu.table = NULL) { - modalDialog( - title = "Custom Unit", - tagList( - # id - fluidRow( - column(6, - offset = 3, - textInput( - ns("modal_id"), - label = withRedStar("Unit identifier"), - placeholder = "e.g. milligramsPerGram", - value = if (!is.na(values[1])) values[1] else NULL - ), - # unitType - textInput( - ns("modal_unitType"), - label = withRedStar("Physical property types the unit belongs to"), - placeholder = "e.g. mass", - value = if (!is.na(values[2])) values[2] else NULL - ), - # ParentSI - selectInput( - ns("modal_parentSI"), - label = withRedStar("Parent unit in SI"), - choices = main.env$FORMATS$units[-1], - selected = if (!is.na(values[3])) values[3] else NULL - ), - # MultiplierToSI - numericInput( - ns("modal_multiplier"), - label = withRedStar("Numeric multiplier computed from Parent unit in SI"), - value = 1, - ), - # Description - textAreaInput( - ns("modal_description"), - label = withRedStar("Unit description"), - placeholder = "e.g. milligrams per gram", - value = if (!is.na(values[5])) values[5] else NULL + sapply( + seq(dim(rv$current.table)[1]), + fields = colnames(rv$current.table)[-1], # not Attribute Name + function(row.index, fields) { + + # TODO Update style: to correct + # updateCollapse( + # session = session, + # NS(id, "collapse"), + # style = filled + # ) + + # Preview ==== + preview.column <- colnames(rv$current.preview)[row.index] + output[[paste0("preview-", preview.column)]] <- renderTable(rv$current.preview[[preview.column]]) + + # Annotate ==== + # annotateId <- paste( + # "annotate", + # isolate(rv$current.file), + # row.index, + # sep = "-" + # ) + # + # .tmp <- callModule( + # annotate, annotateId, + # save.variable, main.env, rv, row.index + # ) + + # Input ==== + lapply(fields, function(colname) { + inputId <- paste( + isolate(rv$current.file), + row.index, + sep = "-" ) - ) - ) # end of fluidRow - ), - easyClose = FALSE, - footer = tagList( - actionButton(ns("modal_cancel"), "Cancel"), - actionButton(ns("modal_submit"), "Submit") - ) - ) - } - - # * CU server ---- - # Cancel - onclick("modal_cancel", { - req(isTRUE(rv$modal.on)) - - # Close modal - rv$modal.on <- FALSE - removeModal() + + obs <- attributeInput( + inputId, + rv, + row.index, + colname, + obs, + curt + ) + }) # end of lapply colname + } # end of *in situ* function + ) # end of sapply : row.index + }) # end of observeEvent - isolate({ - updateSelectInput( - session, - paste(rv$unit.id, collapse = "-"), - selected = main.env$FORMATS$units[2] + # Custom units ---- + observe({ + curt$depend() + .current.table <- isolate(rv$current.table) + modal.on <- isolate(rv$modal.on) + req(any(.current.table$unit == "custom")) + + rv$unit.id <- c( + rv$current.file, + which(.current.table$unit == "custom"), + "unit" ) + + row <- rv$unit.id[2] + class <- .current.table[row, "class"] + + if (class == "numeric" && + modal.on == FALSE) { + rv$cu.values <- rv$cu.table %>% + dplyr::filter(grepl(class, id)) + if (any(dim(rv$cu.values) == 0)) { + rv$cu.values <- rep(NA, 5) + } + + showModal(CU_Modal(rv$cu.values, cu.table = rv$cu.table)) + + rv$modal.on <- TRUE + + isolate({ + rv$current.table[row, "unit"] <- "" + }) + } }) - rv$unit.id <- character() # reset to default - }) - - # Submit button en/disable - observe({ - req(isTRUE(rv$modal.on)) - # type a new one - if (!input$modal_id %in% rv$cu.table$id && - input$modal_id != "custom" && - isTruthy(input$modal_id) && - isTruthy(input$modal_unitType) && - isTruthy(input$modal_parentSI) && - isTruthy(input$modal_multiplier) && - isTruthy(input$modal_description)) { - shinyjs::enable("modal_submit") - } else { - shinyjs::disable("modal_submit") + CU_Modal <- function(values = rep(NA, 5), cu.table = NULL) { + modalDialog( + title = "Custom Unit", + tagList( + # id + fluidRow( + column(6, + offset = 3, + textInput( + NS(id, "modal_id"), + label = withRedStar("Unit identifier"), + placeholder = "e.g. milligramsPerGram", + value = if (!is.na(values[1])) values[1] else NULL + ), + # unitType + textInput( + NS(id, "modal_unitType"), + label = withRedStar("Physical property types the unit belongs to"), + placeholder = "e.g. mass", + value = if (!is.na(values[2])) values[2] else NULL + ), + # ParentSI + selectInput( + NS(id, "modal_parentSI"), + label = withRedStar("Parent unit in SI"), + choices = main.env$FORMATS$units[-1], + selected = if (!is.na(values[3])) values[3] else NULL + ), + # MultiplierToSI + numericInput( + NS(id, "modal_multiplier"), + label = withRedStar("Numeric multiplier computed from Parent unit in SI"), + value = 1, + ), + # Description + textAreaInput( + NS(id, "modal_description"), + label = withRedStar("Unit description"), + placeholder = "e.g. milligrams per gram", + value = if (!is.na(values[5])) values[5] else NULL + ) + ) + ) # end of fluidRow + ), + easyClose = FALSE, + footer = tagList( + actionButton(NS(id, "modal_cancel"), "Cancel"), + actionButton(NS(id, "modal_submit"), "Submit") + ) + ) } - }) - - # Submit - observeEvent(input$modal_submit, - { + + # * CU server ---- + # Cancel + onclick("modal_cancel", { req(isTRUE(rv$modal.on)) # Close modal - removeModal() rv$modal.on <- FALSE + removeModal() - isolate({ - rv$cu.values <- c( - input$modal_id, - input$modal_unitType, - input$modal_parentSI, - input$modal_multiplier, - input$modal_description - ) - }) - - # Update CU values - if (rv$cu.values[1] %in% rv$cu.table$id) { - rv$cu.table <- rv$cu.table %>% - dplyr::filter(id = rv$cu.values[1]) %>% - base::replace(values = rv$cu.values) - } # Add CU values - else { - names(rv$cu.values) <- colnames(rv$cu.table) - rv$cu.table[dim(rv$cu.table)[1] + 1,] <- rv$cu.values - } - # update input UI - rv$units.list <- unique(c( - rv$cu.values["id"], - rv$units.list - )) isolate({ updateSelectInput( session, paste(rv$unit.id, collapse = "-"), - choices = rv$units.list, - selected = rv$cu.values["id"] + selected = main.env$FORMATS$units[2] ) }) + rv$unit.id <- character() # reset to default + }) + + # Submit button en/disable + observe({ + req(isTRUE(rv$modal.on)) - row <- rv$unit.id[2] - rv$current.table[row, "unit"] <- rv$cu.values["id"] - }, - priority = 1 - ) - - output$CUUI <- renderTable({ - validate( - need(isTruthy(unlist(rv$cu.table)), "No custom units registered") + # type a new one + if (!input$modal_id %in% rv$cu.table$id && + input$modal_id != "custom" && + isTruthy(input$modal_id) && + isTruthy(input$modal_unitType) && + isTruthy(input$modal_parentSI) && + isTruthy(input$modal_multiplier) && + isTruthy(input$modal_description)) { + shinyjs::enable("modal_submit") + } else { + shinyjs::disable("modal_submit") + } + }) + + # Submit + observeEvent(input$modal_submit, + { + req(isTRUE(rv$modal.on)) + + # Close modal + removeModal() + rv$modal.on <- FALSE + + isolate({ + rv$cu.values <- c( + input$modal_id, + input$modal_unitType, + input$modal_parentSI, + input$modal_multiplier, + input$modal_description + ) + }) + + # Update CU values + if (rv$cu.values[1] %in% rv$cu.table$id) { + rv$cu.table <- rv$cu.table %>% + dplyr::filter(id = rv$cu.values[1]) %>% + base::replace(values = rv$cu.values) + } # Add CU values + else { + names(rv$cu.values) <- colnames(rv$cu.table) + rv$cu.table[dim(rv$cu.table)[1] + 1,] <- rv$cu.values + } + # update input UI + rv$units.list <- unique(c( + rv$cu.values["id"], + rv$units.list + )) + isolate({ + updateSelectInput( + session, + paste(rv$unit.id, collapse = "-"), + choices = rv$units.list, + selected = rv$cu.values["id"] + ) + }) + + row <- rv$unit.id[2] + rv$current.table[row, "unit"] <- rv$cu.values["id"] + }, + priority = 1 ) - return(rv$cu.table) - }) - - # Saves ----------------------------------------------------- - # observeEvent(rv$tables, { - observe( - { - main.env$EAL$current[2] <- FALSE - req( - length(rv$tables) != 0 && - !any(sapply(rv$tables, identical, y = data.frame())) - ) - - main.env$EAL$current[2] <- all( - unlist( - lapply( - rv$tables, - function(table) { - isTruthy(table) && - all(sapply(table$attributeName, isTruthy)) && - all(sapply(table$attributeDefinition, isTruthy)) && - all(sapply(table$class, isTruthy)) && - !any(grepl("!Add.*here!", table$unit)) && - !any(grepl("!Add.*here!", table$dateTimeFormatString)) - } - ) # lapply - ) # unlist - ) # all - }, - priority = -1 - ) - - observeEvent(NSB$SAVE, - { - req(utils::tail(main.env$EAL$history, 1) == "Attributes") - - save.variable <- saveReactive( - save.variable = savevar, - rv = list(Attributes = rv) + + output$CUUI <- renderTable({ + validate( + need(isTruthy(unlist(rv$cu.table)), "No custom units registered") ) - }, - label = "Save_Attributes", - ignoreInit = TRUE - ) - - # en/disable buttons - observeEvent(rv$current.file, { - req( - isTruthy(names(input)) && - isTruthy(names(rv$current.file)) + return(rv$cu.table) + }) + + # Saves ---- + # observeEvent(rv$tables, { + observe( + { + main.env$EAL$completed <- FALSE + req( + length(rv$tables) != 0 && + !any(sapply(rv$tables, identical, y = data.frame())) + ) + + main.env$EAL$completed <- all( + unlist( + lapply( + rv$tables, + function(table) { + isTruthy(table) && + all(sapply(table$attributeName, isTruthy)) && + all(sapply(table$attributeDefinition, isTruthy)) && + all(sapply(table$class, isTruthy)) && + !any(grepl("!Add.*here!", table$unit)) && + !any(grepl("!Add.*here!", table$dateTimeFormatString)) + } + ) # lapply + ) # unlist + ) # all + }, + priority = -1 ) - if (rv$current.file == 1) { - shinyjs::disable("file_prev") - } else { - shinyjs::enable("file_prev") - } - if (rv$current.file == length(rv$filenames)) { - shinyjs::disable("file_next") - } else { - shinyjs::enable("file_next") - } - }) - - # Process data ----------------------------------------------------- - observeEvent(NSB$NEXT, - { - req(main.env$EAL$current[1] == "Attributes") - - withProgress({ - setProgress(0.5, "Saving metadata") + # observeEvent(NSB$SAVE, + shinyjs::onclick( + "fill-wizard-save", + asis = TRUE, + add = TRUE, + { + req(utils::tail(main.env$EAL$history, 1) == "Attributes") save.variable <- saveReactive( save.variable = savevar, rv = list(Attributes = rv) ) + }, + label = "Save_Attributes", + ignoreInit = TRUE + ) + + # en/disable buttons + observeEvent(rv$current.file, { + req( + isTruthy(names(input)) && + isTruthy(names(rv$current.file)) + ) + + if (rv$current.file == 1) { + shinyjs::disable("file_prev") + } else { + shinyjs::enable("file_prev") + } + if (rv$current.file == length(rv$filenames)) { + shinyjs::disable("file_next") + } else { + shinyjs::enable("file_next") + } + }) + + # Process data ---- + observeEvent(EAL$.next, + { + req(main.env$EAL$current == "Attributes") - # for each attribute data frame - setProgress(0.8, "Resolving catvar templates") - .do.template.catvars <- sapply( - seq_along(rv$filenames), - function(cur_ind) { - - # check for direction: CustomUnits or CatVars - return(isTRUE("categorical" %in% rv$tables[[cur_ind]][, "class"])) + withProgress({ + setProgress(0.5, "Saving metadata") + + save.variable <- saveReactive( + save.variable = savevar, + rv = list(Attributes = rv) + ) + + # for each attribute data frame + setProgress(0.8, "Resolving catvar templates") + .do.template.catvars <- sapply( + seq_along(rv$filenames), + function(cur_ind) { + + # check for direction: CustomUnits or CatVars + return(isTRUE("categorical" %in% rv$tables[[cur_ind]][, "class"])) + } + ) %>% + unlist() %>% + any() + + # EMLAL: template new fields if needed + if (isTRUE(.do.template.catvars)) { + try( + EMLassemblyline::template_categorical_variables( + path = save.variable$emlal$SelectDP$dp.metadata.path, + data.path = save.variable$emlal$SelectDP$dp.data.path + ) + ) } - ) %>% - unlist() %>% - any() - - # EMLAL: template new fields if needed - if (isTRUE(.do.template.catvars)) { + + setProgress(0.9, "Templating geographic coverage") try( - EMLassemblyline::template_categorical_variables( + EMLassemblyline::template_geographic_coverage( path = save.variable$emlal$SelectDP$dp.metadata.path, - data.path = save.variable$emlal$SelectDP$dp.data.path + data.path = save.variable$emlal$SelectDP$dp.data.path, + empty = TRUE, + write.file = TRUE ) ) - } - - setProgress(0.9, "Templating geographic coverage") - try( - EMLassemblyline::template_geographic_coverage( - path = save.variable$emlal$SelectDP$dp.metadata.path, - data.path = save.variable$emlal$SelectDP$dp.data.path, - empty = TRUE, - write.file = TRUE - ) - ) - - if (isFALSE(.do.template.catvars)) { - isolate(main.env$EAL$navigate <- main.env$EAL$navigate + 1) - } - incProgress(0.1) - }) - }, - priority = 1, - ignoreInit = TRUE - ) - - # Output ----------------------------------------------------- - return(save.variable) + + if (isFALSE(.do.template.catvars)) { + isolate(main.env$EAL$page <- main.env$EAL$page + 1) + } + incProgress(0.1) + }) + }, + priority = 1, + ignoreInit = TRUE + ) + + # Output ---- + return(save.variable) + }) } diff --git a/R/eal_3_attributeInput.R b/R/eal_3_attributeInput.R index f1afe50..0c155d4 100644 --- a/R/eal_3_attributeInput.R +++ b/R/eal_3_attributeInput.R @@ -101,7 +101,7 @@ attributeInput <- function(input, output, session, value = .val ) showNotification( - id = session$ns("mvc_update"), + id = session$NS(id, "mvc_update"), ui = HTML("missingValueCode fields are limited to a single word."), duration = 3, diff --git a/R/eal_4_CatVars.R b/R/eal_4_CatVars.R index 87b5658..0417133 100644 --- a/R/eal_4_CatVars.R +++ b/R/eal_4_CatVars.R @@ -1,7 +1,7 @@ #' @import shiny -CatVarsUI <- function(id, title, dev) { +CatVarsUI <- function(id, main.env) { ns <- NS(id) - + return( fluidPage( fluidRow( @@ -10,7 +10,7 @@ CatVarsUI <- function(id, title, dev) { column( 1, actionButton( - ns("file_prev"), + NS(id, "file_prev"), "", icon("chevron-left") ) @@ -18,14 +18,14 @@ CatVarsUI <- function(id, title, dev) { column( 10, uiOutput( - ns("current_file"), + NS(id, "current_file"), inline = TRUE ) ), column( 1, actionButton( - ns("file_next"), + NS(id, "file_next"), "", icon("chevron-right") ) @@ -33,7 +33,7 @@ CatVarsUI <- function(id, title, dev) { style = "padding: 5px;" ), # content form - uiOutput(ns("edit_catvar")) + uiOutput(NS(id, "edit_catvar")) ) ) # end of fluidPage ) # end of return @@ -45,231 +45,228 @@ CatVarsUI <- function(id, title, dev) { #' @importFrom shinyjs onclick #' #' @noRd -CatVars <- function(input, output, session, - save.variable, main.env, NSB) { - ns <- session$ns - - if (main.env$DEV) { -shinyjs::onclick("dev", +CatVars <- function(id, main.env) { + moduleServer(id, function(input, output, session){ + save.variable <- main.env$save.variable + ns <- session$ns + + # variables initialization ---- + rv <- reactiveValues( + catvar.files = list.files( + save.variable$emlal$SelectDP$dp.metadata.path, + pattern = "catvar", + full.names = TRUE + ), + current.index = 1 + ) + + # update current file + observeEvent(rv$current.index, { - req(main.env$EAL$navigate == 4) - browser() + rv$current.file <- basename(rv$catvar.files[rv$current.index]) }, - asis = TRUE + priority = 1, + ignoreInit = FALSE ) - } - - # variables initialization ----------------------------------------------------- - rv <- reactiveValues( - catvar.files = list.files( - save.variable$emlal$SelectDP$dp.metadata.path, - pattern = "catvar", - full.names = TRUE - ), - current.index = 1 - ) - - # update current file - observeEvent(rv$current.index, - { - rv$current.file <- basename(rv$catvar.files[rv$current.index]) - }, - priority = 1, - ignoreInit = FALSE - ) - - # Set each reactivevalues per file - sapply(rv$catvar.files, function(file.path) { - file.name <- basename(file.path) - rv[[file.name]] <- reactiveValues() - - # * Init data frame ==== - rv[[file.name]]$CatVars <- fread( - file.path, - data.table = FALSE, stringsAsFactors = FALSE, - na.strings = "NA" - ) %>% - dplyr::mutate( - definition = if (definition == "NA" || is.na(definition)) { - paste("Value:", code, "for attribute:", attributeName) - } else { - definition + + # Set each reactivevalues per file + sapply(rv$catvar.files, function(file.path) { + file.name <- basename(file.path) + rv[[file.name]] <- reactiveValues() + + # * Init data frame ==== + rv[[file.name]]$CatVars <- fread( + file.path, + data.table = FALSE, stringsAsFactors = FALSE, + na.strings = "NA" + ) %>% + dplyr::mutate( + definition = if (definition == "NA" || is.na(definition)) { + paste("Value:", code, "for attribute:", attributeName) + } else { + definition + } + ) + + # * Write UI ==== + .content <- lapply( + unique(rv[[file.name]]$CatVars$attributeName), + function(attribute) { + # get codes aka values for `attribute` in catvar_*.txt + codes <- rv[[file.name]]$CatVars %>% + dplyr::filter(attributeName == attribute) %>% + dplyr::select(code) + + bsCollapsePanel( + title = attribute, + # value = attribute, + ... = tagList( + lapply(unlist(codes), function(cod) { + if(is.na(cod)) + cod <- "NA" + + input.id <- paste( + attribute, + cod %>% + gsub("[ [:punct:]]", "", .), + sep = "-" + ) + + textAreaInput( + ns(input.id), + cod, + value = rv[[file.name]]$CatVars %>% + dplyr::filter(attributeName == attribute, code == cod) %>% + dplyr::select(definition) %>% + unique + ) + }) + ) # end of "tagapply" -- text areas + ) # end of bsCollapsePanel } + ) # end of "tagapply" -- collapse boxes + + rv[[file.name]]$UI <- do.call( + bsCollapse, + c( + .content, + id = file.name, + multiple = FALSE + ) ) - - # * Write UI ==== - .content <- lapply( - unique(rv[[file.name]]$CatVars$attributeName), - function(attribute) { - # get codes aka values for `attribute` in catvar_*.txt - codes <- rv[[file.name]]$CatVars %>% - dplyr::filter(attributeName == attribute) %>% - dplyr::select(code) - - bsCollapsePanel( - title = attribute, - # value = attribute, - ... = tagList( - lapply(unlist(codes), function(cod) { - if(is.na(cod)) - cod <- "NA" - - input.id <- paste( - attribute, - cod %>% - gsub("[ [:punct:]]", "", .), - sep = "-" - ) - - textAreaInput( - ns(input.id), - cod, - value = rv[[file.name]]$CatVars %>% - dplyr::filter(attributeName == attribute, code == cod) %>% - dplyr::select(definition) %>% - unique - ) - }) - ) # end of "tagapply" -- text areas - ) # end of bsCollapsePanel + + # * Write server ==== + rv[[file.name]]$obs <- sapply( + seq(dim(rv[[file.name]]$CatVars)[1]), + function(row) { + input.id <- paste( + rv[[file.name]]$CatVars$attributeName[row], + rv[[file.name]]$CatVars$code[row] %>% + gsub("[ [:punct:]]", "", .), + sep = "-" + ) + + return( + observeEvent(input[[input.id]], + { + req(input[[input.id]]) + rv[[file.name]]$CatVars[row, "definition"] <- input[[input.id]] + }, + suspended = TRUE + ) + ) + } + ) + }) + + # Navigation buttons ---- + # Previous file + observeEvent(input$file_prev, { + req(rv$current.index, rv$catvar.files) + save.variable$emlal$CatVars[[rv$current.file]] <- rv[[rv$current.file]]$CatVars + if (rv$current.index > 1) { + rv$current.index <- rv$current.index - 1 } - ) # end of "tagapply" -- collapse boxes + }) - rv[[file.name]]$UI <- do.call( - bsCollapse, - c( - .content, - id = file.name, - multiple = FALSE - ) - ) - - # * Write server ==== - rv[[file.name]]$obs <- sapply( - seq(dim(rv[[file.name]]$CatVars)[1]), - function(row) { - input.id <- paste( - rv[[file.name]]$CatVars$attributeName[row], - rv[[file.name]]$CatVars$code[row] %>% - gsub("[ [:punct:]]", "", .), - sep = "-" - ) - - return( - observeEvent(input[[input.id]], - { - req(input[[input.id]]) - rv[[file.name]]$CatVars[row, "definition"] <- input[[input.id]] - }, - suspended = TRUE - ) - ) + # Next file + observeEvent(input$file_next, { + req(rv$current.index, rv$catvar.files) + save.variable$emlal$CatVars[[rv$current.file]] <- rv[[rv$current.file]]$CatVars + if (rv$current.index < length(rv$catvar.files)) { + rv$current.index <- rv$current.index + 1 } - ) - }) - - # Navigation buttons ----------------------------------------------------- - # Previous file - observeEvent(input$file_prev, { - req(rv$current.index, rv$catvar.files) - save.variable$emlal$CatVars[[rv$current.file]] <- rv[[rv$current.file]]$CatVars - if (rv$current.index > 1) { - rv$current.index <- rv$current.index - 1 - } - }) - - # Next file - observeEvent(input$file_next, { - req(rv$current.index, rv$catvar.files) - save.variable$emlal$CatVars[[rv$current.file]] <- rv[[rv$current.file]]$CatVars - if (rv$current.index < length(rv$catvar.files)) { - rv$current.index <- rv$current.index + 1 - } - }) - - # Current file - output$current_file <- renderUI({ - tags$div( - rv$current.file, - class = "ellipsis", - style = paste0( - "display: inline-block; + }) + + # Current file + output$current_file <- renderUI({ + tags$div( + rv$current.file, + class = "ellipsis", + style = paste0( + "display: inline-block; font-size:14pt; text-align:center; width:100%; background: linear-gradient(90deg, #3c8dbc ", - round(100 * rv$current.index / length(rv$catvar.files)), - "%, white ", - round(100 * rv$current.index / length(rv$catvar.files)), - "%);" + round(100 * rv$current.index / length(rv$catvar.files)), + "%, white ", + round(100 * rv$current.index / length(rv$catvar.files)), + "%);" + ) ) + }) + + # Set UI ---- + output$edit_catvar <- renderUI({ + validate( + need(rv[[rv$current.file]]$UI, "No UI set.") + ) + rv[[rv$current.file]]$UI + }) # end of renderUI + + # Set Server ---- + + # Suspend observers + observeEvent(rv$current.index, + { + req(rv$current.file) + sapply(rv[[rv$current.file]]$obs, function(obs) { + obs$suspend() + }) + }, + priority = 2 ) - }) - - # Set UI ----------------------------------------------------- - output$edit_catvar <- renderUI({ - validate( - need(rv[[rv$current.file]]$UI, "No UI set.") - ) - rv[[rv$current.file]]$UI - }) # end of renderUI - - # Set Server ----------------------------------------------------- - - # Suspend observers - observeEvent(rv$current.index, - { - req(rv$current.file) - sapply(rv[[rv$current.file]]$obs, function(obs) { - obs$suspend() - }) - }, - priority = 2 - ) - - # Run observers - observeEvent(rv$current.file, - { - req(rv$current.file) - sapply(rv[[rv$current.file]]$obs, function(obs) { - obs$resume() - }) - }, - priority = 0 - ) - - # Saves ----------------------------------------------------- - observe({ - main.env$EAL$current[2] <- all( - sapply(basename(rv$catvar.files), function(file.name) { - all(sapply(rv[[file.name]]$CatVars$definition, isTruthy)) - }) - ) - }) - - observeEvent(NSB$SAVE, { - req(utils::tail(main.env$EAL$history, 1) == "Categorical Variables") - - save.variable <- saveReactive( - save.variable, - rv = list(CatVars = rv) + + # Run observers + observeEvent(rv$current.file, + { + req(rv$current.file) + sapply(rv[[rv$current.file]]$obs, function(obs) { + obs$resume() + }) + }, + priority = 0 ) - }) - - # Process data ----------------------------------------------------- - observeEvent(NSB$NEXT, - { - req(main.env$EAL$current[2] == "Categorical Variables") - + + # Saves ---- + observe({ + main.env$EAL$completed <- all( + sapply(basename(rv$catvar.files), function(file.name) { + all(sapply(rv[[file.name]]$CatVars$definition, isTruthy)) + }) + ) + }) + + # observeEvent(NSB$SAVE, + shinyjs::onclick( + "fill-wizard-save", + asis = TRUE, + add = TRUE, + { + req(utils::tail(main.env$EAL$history, 1) == "Categorical Variables") + save.variable <- saveReactive( save.variable, rv = list(CatVars = rv) ) - }, - priority = 1, - ignoreInit = TRUE - ) - - # Output ----------------------------------------------------- - return(save.variable) + }) + + # Process data ---- + observeEvent(EAL$.next, + { + req(main.env$EAL$current == "Categorical Variables") + + save.variable <- saveReactive( + save.variable, + rv = list(CatVars = rv) + ) + }, + priority = 1, + ignoreInit = TRUE + ) + + # Output ---- + return(save.variable) + }) } diff --git a/R/eal_5_GeoCovInput.R b/R/eal_5_GeoCovInput.R index 871e6dd..8a705c7 100644 --- a/R/eal_5_GeoCovInput.R +++ b/R/eal_5_GeoCovInput.R @@ -29,7 +29,7 @@ GeoCovInputUI <- function(id, site.id, rmv.id, default = NULL) { id = site.id, fluidRow( column(2, "Description", style = "text-align: right"), - column(9, textInput(ns("site_description"), def.site, site.id)), + column(9, textInput(NS(id, "site_description"), def.site, site.id)), column( 1, actionButton( @@ -82,7 +82,7 @@ GeoCovInputUI <- function(id, site.id, rmv.id, default = NULL) { GeoCovInput <- function(input, output, session, rv, rmv.id, site.id, ref) { - # Metadata acquisition ----------------------------------------------------- + # Metadata acquisition ---- local.rv <- reactiveValues( id = ref, geographicDescription = "", @@ -121,7 +121,7 @@ GeoCovInput <- function(input, output, session, priority = 1 ) - # Metadata save ----------------------------------------------------- + # Metadata save ---- observeEvent( { input$site_description @@ -145,7 +145,7 @@ GeoCovInput <- function(input, output, session, priority = 0 ) - # Remove UI ----------------------------------------------------- + # Remove UI ---- shinyjs::onclick(rmv.id, { # remove the UI removeUI(selector = paste0("#", site.id), immediate = TRUE) @@ -156,7 +156,7 @@ GeoCovInput <- function(input, output, session, rv$id <- rv$id[-ind] }) - # Output ----------------------------------------------------- + # Output ---- return(rv) } @@ -167,12 +167,12 @@ GeoCovInput <- function(input, output, session, insertGeoCovInput <- function(id, rv, ns, default = NULL) { # !!! warning: rv = rv$custom here !!! - # initialize IDs ----------------------------------------------------- + # initialize IDs ---- div.id <- id site.id <- paste0("site_", div.id) rmv.id <- paste0("rmv_", div.id) - # Proper module server ----------------------------------------------------- + # Proper module server ---- # create the UI new.ui <- GeoCovInputUI(ns(div.id), site.id, rmv.id, default = default) @@ -180,12 +180,9 @@ insertGeoCovInput <- function(id, rv, ns, default = NULL) { insertUI(selector = "#inserthere", ui = new.ui) # create the server - rv <- callModule( - GeoCovInput, div.id, - rv, rmv.id, site.id, id - ) + rv <- GeoCovInput(div.id, rv, rmv.id, site.id, id) - # Output ----------------------------------------------------- + # Output ---- return(rv) } diff --git a/R/eal_5_geographicCoverage.R b/R/eal_5_geographicCoverage.R index ace0562..543bf8c 100644 --- a/R/eal_5_geographicCoverage.R +++ b/R/eal_5_geographicCoverage.R @@ -2,7 +2,7 @@ #' @importFrom shinyjs hidden #' #' @noRd -GeoCovUI <- function(id, title, dev) { +GeoCovUI <- function(id, main.env) { ns <- NS(id) return( @@ -18,21 +18,21 @@ GeoCovUI <- function(id, title, dev) { and one or two others for latitude and longitude. Southern latitude and western longitude shall be noted with negative values."), bsCollapse( - id = ns("method"), + id = NS(id, "method"), bsCollapsePanel( title = "Use dataset's geographic variables", value = 1, tagList( - uiOutput(ns("site-ui")), - uiOutput(ns("latitude-ui")), + uiOutput(NS(id, "site-ui")), + uiOutput(NS(id, "latitude-ui")), div( - id = ns("latiWarn"), - textOutput(ns("latitude-warning")) + id = NS(id, "latiWarn"), + textOutput(NS(id, "latitude-warning")) ), - uiOutput(ns("longitude-ui")), + uiOutput(NS(id, "longitude-ui")), div( - id = ns("longWarn"), - textOutput(ns("longitude-warning")) + id = NS(id, "longWarn"), + textOutput(NS(id, "longitude-warning")) ) ) ), @@ -42,13 +42,13 @@ GeoCovUI <- function(id, title, dev) { fluidRow( column( 2, - actionButton(ns("addui"), "", icon("plus")), + actionButton(NS(id, "addui"), "", icon("plus")), ), column( 10, hidden( tags$div( - id = ns("slider_tips"), + id = NS(id, "slider_tips"), HTML("You can detail a more precise number by using the left/right (or down/up) arrows of your keyboard. Precision can be given at 0.01 °. Items can be removed by using the @@ -75,20 +75,12 @@ GeoCovUI <- function(id, title, dev) { #' @importFrom shinyjs onclick show #' #' @noRd -GeoCov <- function(input, output, session, save.variable, main.env, NSB) { +GeoCov <- function(id, main.env) { + moduleServer(id, function(input, output, session){ + save.variable <- main.env$save.variable ns <- session$ns - if (main.env$DEV) { - shinyjs::onclick("dev", - { - req(main.env$EAL$navigate == 5) - browser() - }, - asis = TRUE - ) - } - - # Variable initialization ----------------------------------------------------- + # Variable initialization ---- # Reactive Values rv <- reactiveValues( @@ -136,7 +128,7 @@ GeoCov <- function(input, output, session, save.variable, main.env, NSB) { } } - # Pre-fill ----------------------------------------------------- + # Pre-fill ---- # * Set choices ==== columns <- lapply( seq_along(save.variable$emlal$Attributes), @@ -230,7 +222,7 @@ GeoCov <- function(input, output, session, save.variable, main.env, NSB) { label = "EAL5 init choices" ) - # Input management ----------------------------------------------------- + # Input management ---- { # * Site description ---- output$`site-ui` <- renderUI({ @@ -248,7 +240,7 @@ GeoCov <- function(input, output, session, save.variable, main.env, NSB) { } selectInput( - ns("site"), + NS(id, "site"), "Choose a column for sites:", c("None" = "", rv$columns$choices$sites), selected = .site.name @@ -298,7 +290,7 @@ GeoCov <- function(input, output, session, save.variable, main.env, NSB) { # Update UI selectizeInput( - ns("latitude"), + NS(id, "latitude"), "Choose a column for latitude:", c("None" = "", rv$columns$choices$coords), selected = .lat.cols, @@ -334,7 +326,7 @@ GeoCov <- function(input, output, session, save.variable, main.env, NSB) { label = "EAL5 get latitude" ) - # * Longitude ----------------------------------------------------- + # * Longitude ---- output$`longitude-ui` <- renderUI({ isolate({ .lon.cols <- printReactiveValues(rv$columns$lon) @@ -355,7 +347,7 @@ GeoCov <- function(input, output, session, save.variable, main.env, NSB) { # Update UI selectizeInput( - ns("longitude"), + NS(id, "longitude"), "Choose a column for longitude:", c("None" = "", rv$columns$choices$coords), selected = .lon.cols, @@ -391,7 +383,7 @@ GeoCov <- function(input, output, session, save.variable, main.env, NSB) { ) } - # Fill custom ----------------------------------------------------- + # Fill custom ---- # * Setup ---- if (dim(rv$custom$coordinates)[1] > 0) { sapply(1:nrow(rv$custom$coordinates), function(ind) { @@ -415,7 +407,7 @@ GeoCov <- function(input, output, session, save.variable, main.env, NSB) { ) }) - # Saves ----------------------------------------------------- + # Saves ---- observeEvent( { rv$columns$site$col @@ -438,13 +430,17 @@ GeoCov <- function(input, output, session, save.variable, main.env, NSB) { ) observe({ - main.env$EAL$current[2] <- any( + main.env$EAL$completed <- any( isTRUE(rv$custom$complete), isTRUE(rv$columns$complete) ) }) - observeEvent(NSB$SAVE, + # observeEvent(NSB$SAVE, + shinyjs::onclick( + "fill-wizard-save", + asis = TRUE, + add = TRUE, { req(utils::tail(main.env$EAL$history, 1) == "Geographic Coverage") @@ -461,23 +457,23 @@ GeoCov <- function(input, output, session, save.variable, main.env, NSB) { ignoreInit = TRUE ) - # Process data ----------------------------------------------------- + # Process data ---- # * Previous ---- - observeEvent(NSB$PREV, + observeEvent(EAL$.prev, { - req(main.env$EAL$current[1] == "Geographic Coverage") + req(main.env$EAL$current == "Geographic Coverage") if (!"Categorical Variables" %in% main.env$EAL$history) { - main.env$EAL$navigate <- main.env$EAL$navigate - 1 + main.env$EAL$page <- main.env$EAL$page - 1 } }, ignoreInit = TRUE ) # * Next ---- - observeEvent(NSB$NEXT, + observeEvent(EAL$.next, { - req(main.env$EAL$current[1] == "Geographic Coverage") + req(main.env$EAL$current == "Geographic Coverage") # Create modal choices <- c( @@ -492,7 +488,7 @@ GeoCov <- function(input, output, session, save.variable, main.env, NSB) { tagList( "You are getting ready to proceed. Please select one of the following:", radioButtons( - ns("method"), + NS(id, "method"), "Method for Geographic Coverage:", choices = choices ) @@ -500,7 +496,7 @@ GeoCov <- function(input, output, session, save.variable, main.env, NSB) { easyClose = FALSE, footer = tagList( modalButton("Cancel"), - actionButton(ns("confirm"), "Proceed") + actionButton(NS(id, "confirm"), "Proceed") ) ) @@ -512,8 +508,8 @@ GeoCov <- function(input, output, session, save.variable, main.env, NSB) { observeEvent(input$confirm, { removeModal() - main.env$EAL$navigate <- 6 - NSB$tagList <- tagList() + main.env$EAL$page <- 6 + EAL$tag.list <- tagList() .method <- input$method @@ -529,6 +525,7 @@ GeoCov <- function(input, output, session, save.variable, main.env, NSB) { ) }, ignoreInit = TRUE) - # Output ----------------------------------------------------- + # Output ---- return(save.variable) +}) } diff --git a/R/eal_6_taxonomicCoverage.R b/R/eal_6_taxonomicCoverage.R index 526077f..044ddd1 100644 --- a/R/eal_6_taxonomicCoverage.R +++ b/R/eal_6_taxonomicCoverage.R @@ -2,21 +2,21 @@ #' @importFrom shinyjs hidden disabled #' #' @noRd -TaxCovUI <- function(id, title, dev) { +TaxCovUI <- function(id, main.env) { ns <- NS(id) - + return( fluidPage( fluidRow( column( 6, - uiOutput(ns("taxa.table")), - uiOutput(ns("taxa.col")) + uiOutput(NS(id, "taxa.table")), + uiOutput(NS(id, "taxa.col")) ), column( 6, - uiOutput(ns("taxa.name.type")), - uiOutput(ns("taxa.authority")) + uiOutput(NS(id, "taxa.name.type")), + uiOutput(NS(id, "taxa.authority")) ) ) ) # end of fluidPage @@ -30,291 +30,289 @@ TaxCovUI <- function(id, title, dev) { #' @importFrom shinyjs onclick #' #' @noRd -TaxCov <- function(input, output, session, - save.variable, main.env, NSB) { - ns <- session$ns - if (main.env$DEV) { - shinyjs::onclick("dev", - { - req(main.env$EAL$navigate == 6) - browser() - }, - asis = TRUE - ) - } - - # Variable Initialization ----------------------------------------------------- - rv <- reactiveValues( - taxa.table = character(), - taxa.col = character(), - taxa.name.type = character(), - taxa.authority = character(), - complete = FALSE - ) - - if (sapply(printReactiveValues(save.variable$emlal$TaxCov), checkTruth) %>% all()) { - rv$taxa.table <- save.variable$emlal$TaxCov$taxa.table - rv$taxa.col <- save.variable$emlal$TaxCov$taxa.col - rv$taxa.name.type <- save.variable$emlal$TaxCov$taxa.authority - rv$taxa.authority <- save.variable$emlal$TaxCov$taxa.authority - } - - # Set UI ==== - - # * taxa.table ==== - output$taxa.table <- renderUI({ - isolate({ - data.files <- basename(save.variable$emlal$DataFiles$datapath) - value <- rv$taxa.table - if(isFALSE(value %in% data.files)) - value <- NULL - }) +TaxCov <-function(id, main.env) { + moduleServer(id, function(input, output, session){ + save.variable <- main.env$save.variable + ns <- session$ns - selectInput( - ns("taxa.table"), - "Files containing taxonomic references", - choices = data.files, - selected = value, - multiple = FALSE + # Variable Initialization ---- + rv <- reactiveValues( + taxa.table = character(), + taxa.col = character(), + taxa.name.type = character(), + taxa.authority = character(), + complete = FALSE ) - }) - - # * taxa.col ==== - output$taxa.col <- renderUI({ - .ind <- match(rv$taxa.table, save.variable$emlal$DataFiles$name) - if(isTruthy(.ind)) { - choices <- isolate(save.variable$emlal$Attributes[[.ind]]$attributeName) - value <- isolate(rv$taxa.col) - if(isFALSE(value %in% choices)) - value <- NULL - .embed <- tagList - } - else { - choices <- NULL - value <- NULL - .embed <- shinyjs::disabled + + if (sapply(printReactiveValues(save.variable$emlal$TaxCov), checkTruth) %>% all()) { + rv$taxa.table <- save.variable$emlal$TaxCov$taxa.table + rv$taxa.col <- save.variable$emlal$TaxCov$taxa.col + rv$taxa.name.type <- save.variable$emlal$TaxCov$taxa.authority + rv$taxa.authority <- save.variable$emlal$TaxCov$taxa.authority } - .embed( + # Set UI ==== + + # * taxa.table ==== + output$taxa.table <- renderUI({ + isolate({ + data.files <- basename(save.variable$emlal$DataFiles$datapath) + value <- rv$taxa.table + if(isFALSE(value %in% data.files)) + value <- NULL + }) + selectInput( - ns("taxa.col"), - "Columns from selected files", - choices = choices, + NS(id, "taxa.table"), + "Files containing taxonomic references", + choices = data.files, + selected = value, + multiple = FALSE + ) + }) + + # * taxa.col ==== + output$taxa.col <- renderUI({ + .ind <- match(rv$taxa.table, save.variable$emlal$DataFiles$name) + if(isTruthy(.ind)) { + choices <- isolate(save.variable$emlal$Attributes[[.ind]]$attributeName) + value <- isolate(rv$taxa.col) + if(isFALSE(value %in% choices)) + value <- NULL + .embed <- tagList + } + else { + choices <- NULL + value <- NULL + .embed <- shinyjs::disabled + } + + .embed( + selectInput( + NS(id, "taxa.col"), + "Columns from selected files", + choices = choices, + selected = value + ) + ) + }) + + # * taxa.name.type ==== + output$taxa.name.type <- renderUI({ + isolate({ + value <- rv$taxa.name.type + if(isTRUE(value == "both")) + value <- c("scientific", "common") + else if(isFALSE(value %in% c("scientific", "common"))) + value <- NULL + }) + + checkboxGroupInput( + NS(id, "taxa.name.type"), + "Select one or both taxonomic name notation", + c("scientific", "common"), selected = value ) - ) - }) - - # * taxa.name.type ==== - output$taxa.name.type <- renderUI({ - isolate({ - value <- rv$taxa.name.type - if(isTRUE(value == "both")) - value <- c("scientific", "common") - else if(isFALSE(value %in% c("scientific", "common"))) - value <- NULL }) - checkboxGroupInput( - ns("taxa.name.type"), - "Select one or both taxonomic name notation", - c("scientific", "common"), - selected = value + # * taxa.authority ==== + output$taxa.authority <- renderUI({ + isolate({ + taxa.authority <- main.env$FORMATS$taxa.authorities + choices <- taxa.authority$authority + value <- if(isTruthy(rv$taxa.authority)){ + taxa.authority %>% + dplyr::filter(id == rv$taxa.authority) %>% + dplyr::select(authority) + } + }) + + selectInput( + NS(id, "taxa.authority"), + "Select taxonomic authority.ies", + choices = choices, + selected = value, + multiple = TRUE + ) + }) + + # Taxonomic coverage input ---- + + # * Taxa files ==== + observeEvent(input$taxa.table, + { + # invalid-selected/no value(s) + if (!isTruthy(input$taxa.table)) { + shinyjs::disable("taxa.col") + + updateSelectizeInput( + session, + "taxa.col", + choices = list("(None selected)" = NULL) + ) + } + # valid-selected value(s) + else { + shinyjs::enable("taxa.col") + + taxa.col.list <- lapply(input$taxa.table, function(file) { + all.files <- save.variable$emlal$DataFiles + file <- all.files[all.files$name == file, "datapath"] + df <- readDataTable(file, stringsAsFactors = FALSE) + return(colnames(df)) + }) + names(taxa.col.list) <- input$taxa.table + + .update.var <- if (isTRUE(rv$taxa.col %in% taxa.col.list)) + rv$taxa.col + else + NULL + + updateSelectizeInput( + session, + "taxa.col", + choices = taxa.col.list, + selected = .update.var + ) + } + + # save + rv$taxa.table <- list(input$taxa.table) + isolate({save.variable$emlal$TaxCov$taxa.table <- rv$taxa.table}) + }, + priority = -1 ) - }) - - # * taxa.authority ==== - output$taxa.authority <- renderUI({ - isolate({ - taxa.authority <- main.env$FORMATS$taxa.authorities - choices <- taxa.authority$authority - value <- if(isTruthy(rv$taxa.authority)){ - taxa.authority %>% - dplyr::filter(id == rv$taxa.authority) %>% - dplyr::select(authority) + + # * Taxa columns to read ==== + observeEvent(input$taxa.col, { + req(input$taxa.col) + + rv$taxa.col <- input$taxa.col + isolate({save.variable$emlal$TaxCov$taxa.col <- rv$taxa.col}) + }) + + # * Taxa type ==== + observeEvent(input$taxa.name.type, { + req(input$taxa.name.type) + + rv$taxa.name.type <- input$taxa.name.type + + if ("scientific" %in% rv$taxa.name.type && + "common" %in% rv$taxa.name.type) { + rv$taxa.name.type <- "both" } + save.variable$emlal$TaxCov$taxa.name.type <- rv$taxa.name.type + }) + + # * Taxa authority ==== + observeEvent(input$taxa.authority, { + req(input$taxa.authority) + + rv$taxa.authority <- main.env$FORMATS$taxa.authorities %>% + dplyr::filter(authority %in% input$taxa.authority) %>% + dplyr::select(id) %>% + unlist() + save.variable$emlal$TaxCov$taxa.authority <- rv$taxa.authority + }) + + # Saves ---- + main.env$EAL$completed <- TRUE + observe({ + req(main.env$EAL$current == "Taxonomic Coverage") + + rv$complete <- all( + length(rv$taxa.table) > 0 && + length(rv$taxa.col) > 0 && + length(rv$taxa.name.type) > 0 && + length(rv$taxa.authority) > 0 + ) }) - selectInput( - ns("taxa.authority"), - "Select taxonomic authority.ies", - choices = choices, - selected = value, - multiple = TRUE + + # observeEvent(NSB$SAVE, + shinyjs::onclick( + "fill-wizard-save", + asis = TRUE, + add = TRUE, + { + req(utils::tail(main.env$EAL$history, 1) == "Taxonomic Coverage") + + save.variable <- saveReactive( + save.variable = savevar, + rv = list(TaxCov = rv) + ) + }, + ignoreInit = TRUE ) - }) - - # Taxonomic coverage input ----------------------------------------------------- - - # * Taxa files ==== - observeEvent(input$taxa.table, - { - # invalid-selected/no value(s) - if (!isTruthy(input$taxa.table)) { - shinyjs::disable("taxa.col") - - updateSelectizeInput( - session, - "taxa.col", - choices = list("(None selected)" = NULL) + + # Process data ---- + observeEvent(EAL$.next, + { + req(main.env$EAL$current == "Taxonomic Coverage") + + choices <- c( + "Yes - Taxonomic coverage will be written as file" = if (rv$complete) 1 else NULL, + "No - Taxonomic coverage will be left blank" = 0 ) - } - # valid-selected value(s) - else { - shinyjs::enable("taxa.col") - taxa.col.list <- lapply(input$taxa.table, function(file) { - all.files <- save.variable$emlal$DataFiles - file <- all.files[all.files$name == file, "datapath"] - df <- readDataTable(file, stringsAsFactors = FALSE) - return(colnames(df)) - }) - names(taxa.col.list) <- input$taxa.table - - .update.var <- if (isTRUE(rv$taxa.col %in% taxa.col.list)) - rv$taxa.col - else - NULL - - updateSelectizeInput( - session, - "taxa.col", - choices = taxa.col.list, - selected = .update.var + nextTabModal <- modalDialog( + title = "Proceed Taxonomic Coverage", + tagList( + "You are getting ready to proceed.", + radioButtons( + NS(id, "filled"), + "Is Taxonomic Coverage filled?", + choices = choices + ) + ), + footer = tagList( + modalButton("Cancel"), + actionButton(NS(id, "confirm"), "Proceed") + ) ) - } - - # save - rv$taxa.table <- list(input$taxa.table) - isolate({save.variable$emlal$TaxCov$taxa.table <- rv$taxa.table}) - }, - priority = -1 - ) - - # * Taxa columns to read ==== - observeEvent(input$taxa.col, { - req(input$taxa.col) - - rv$taxa.col <- input$taxa.col - isolate({save.variable$emlal$TaxCov$taxa.col <- rv$taxa.col}) - }) - - # * Taxa type ==== - observeEvent(input$taxa.name.type, { - req(input$taxa.name.type) - - rv$taxa.name.type <- input$taxa.name.type - - if ("scientific" %in% rv$taxa.name.type && - "common" %in% rv$taxa.name.type) { - rv$taxa.name.type <- "both" - } - save.variable$emlal$TaxCov$taxa.name.type <- rv$taxa.name.type - }) - - # * Taxa authority ==== - observeEvent(input$taxa.authority, { - req(input$taxa.authority) - - rv$taxa.authority <- main.env$FORMATS$taxa.authorities %>% - dplyr::filter(authority %in% input$taxa.authority) %>% - dplyr::select(id) %>% - unlist() - save.variable$emlal$TaxCov$taxa.authority <- rv$taxa.authority - }) - - # Saves ----------------------------------------------------- - main.env$EAL$current[2] <- TRUE - observe({ - req(main.env$EAL$current[1] == "Taxonomic Coverage") - - rv$complete <- all( - length(rv$taxa.table) > 0 && - length(rv$taxa.col) > 0 && - length(rv$taxa.name.type) > 0 && - length(rv$taxa.authority) > 0 + + showModal(nextTabModal) + }, + ignoreInit = TRUE ) - }) - - observeEvent(NSB$SAVE, - { - req(utils::tail(main.env$EAL$history, 1) == "Taxonomic Coverage") - - save.variable <- saveReactive( - save.variable = savevar, - rv = list(TaxCov = rv) - ) - }, - ignoreInit = TRUE - ) - - # Process data ----------------------------------------------------- - observeEvent(NSB$NEXT, - { - req(main.env$EAL$current[1] == "Taxonomic Coverage") - - choices <- c( - "Yes - Taxonomic coverage will be written as file" = if (rv$complete) 1 else NULL, - "No - Taxonomic coverage will be left blank" = 0 - ) - - nextTabModal <- modalDialog( - title = "Proceed Taxonomic Coverage", - tagList( - "You are getting ready to proceed.", - radioButtons( - ns("filled"), - "Is Taxonomic Coverage filled?", - choices = choices + + observeEvent(input$confirm, { + removeModal() + main.env$EAL$page <- 7 + EAL$tag.list <- tagList() + + # Write files + if (input$filled == "1") { + save.variable <- saveReactive( + save.variable, + rv = list(TaxCov = rv) + ) + + # Template coverage + try( + template_taxonomic_coverage( + save.variable$emlal$SelectDP$dp.metadata.path, + save.variable$emlal$SelectDP$dp.data.path, + taxa.table = rv$taxa.table, + taxa.col = rv$taxa.col, + taxa.name.type = rv$taxa.name.type, + taxa.authority = rv$taxa.authority ) - ), - footer = tagList( - modalButton("Cancel"), - actionButton(ns("confirm"), "Proceed") ) - ) - - showModal(nextTabModal) - }, - ignoreInit = TRUE - ) - - observeEvent(input$confirm, { - removeModal() - main.env$EAL$navigate <- 7 - NSB$tagList <- tagList() - - # Write files - if (input$filled == "1") { - save.variable <- saveReactive( - save.variable, - rv = list(TaxCov = rv) - ) - - # Template coverage - try( - template_taxonomic_coverage( - save.variable$emlal$SelectDP$dp.metadata.path, - save.variable$emlal$SelectDP$dp.data.path, - taxa.table = rv$taxa.table, - taxa.col = rv$taxa.col, - taxa.name.type = rv$taxa.name.type, - taxa.authority = rv$taxa.authority + showNotification( + "Taxonomic Coverage has been written.", + type = "message" ) - ) - showNotification( - "Taxonomic Coverage has been written.", - type = "message" - ) - } - else { - showNotification( - "Taxonomic Coverage has been skipped.", - type = "message" - ) - } + } + else { + showNotification( + "Taxonomic Coverage has been skipped.", + type = "message" + ) + } + }) + + # Output ---- + return(save.variable) }) - - # Output ----------------------------------------------------- - return(save.variable) } diff --git a/R/eal_7_personnel.R b/R/eal_7_personnel.R index 67681f7..b157c84 100644 --- a/R/eal_7_personnel.R +++ b/R/eal_7_personnel.R @@ -1,14 +1,14 @@ #' @import shiny #' @noRd -PersonnelUI <- function(id, title, dev) { +PersonnelUI <- function(id, main.env) { ns <- NS(id) - + return( fluidPage( fluidRow( column( 2, - actionButton(ns("addui"), "", icon("plus")) + actionButton(NS(id, "addui"), "", icon("plus")) ), column( 10, @@ -22,7 +22,7 @@ PersonnelUI <- function(id, title, dev) { fill the remaining fields.

") ) ), - tags$div(id = ns("inserthere")) + tags$div(id = NS(id, "inserthere")) ) # end of fluidPage ) # end of return } @@ -32,180 +32,177 @@ PersonnelUI <- function(id, title, dev) { #' @importFrom data.table fwrite #' #' @noRd -Personnel <- function(input, output, session, save.variable, main.env, NSB) { - ns <- session$ns - - if (main.env$DEV) { - shinyjs::onclick("dev", - { - req(main.env$EAL$navigate == 7) - browser() - }, - asis = TRUE +Personnel <- function(id, main.env) { + moduleServer(id, function(input, output, session){ + save.variable <- main.env$save.variable + ns <- session$ns + + # Variable initialization ---- + rv <- reactiveValues( + Personnel = data.frame( + id = numeric(), + # Basic Identity + givenName = character(), + middleInitial = character(), + surName = character(), + # Contact + organizationName = character(), + electronicMailAddress = character(), + # Personnel information + userId = character(), + role = character(), + # Project information + projectTitle = character(), + fundingAgency = character(), + fundingNumber = character(), + stringsAsFactors = FALSE + ) ) - } - - # Variable initialization ----------------------------------------------------- - rv <- reactiveValues( - Personnel = data.frame( - id = numeric(), - # Basic Identity - givenName = character(), - middleInitial = character(), - surName = character(), - # Contact - organizationName = character(), - electronicMailAddress = character(), - # Personnel information - userId = character(), - role = character(), - # Project information - projectTitle = character(), - fundingAgency = character(), - fundingNumber = character(), - stringsAsFactors = FALSE + + personnel.file <- dir( + save.variable$emlal$SelectDP$dp.metadata.path, + pattern = "ersonnel", + full.names = TRUE ) - ) - - personnel.file <- dir( - save.variable$emlal$SelectDP$dp.metadata.path, - pattern = "ersonnel", - full.names = TRUE - ) - saved.table <- if (isTruthy(personnel.file)) { - data.table::fread(personnel.file, data.table = FALSE, stringsAsFactors = FALSE) - } else if (isTruthy(unlist(save.variable$emlal$Personnel))) { - isolate(save.variable$emlal$Personnel) - } else { - NULL - } - saved.table[is.na(saved.table)] <- "" - if (checkTruth(saved.table)) { - saved.table$id <- c( - saved.table$role[1:2], - seq_along(saved.table$givenName)[-(1:2)] - ) - isolate(rv$Personnel <- saved.table) - - sapply(rv$Personnel$id, function(rvid) { + saved.table <- if (isTruthy(personnel.file)) { + data.table::fread(personnel.file, data.table = FALSE, stringsAsFactors = FALSE) + } else if (isTruthy(unlist(save.variable$emlal$Personnel))) { + isolate(save.variable$emlal$Personnel) + } else { + NULL + } + saved.table[is.na(saved.table)] <- "" + if (checkTruth(saved.table)) { + saved.table$id <- c( + saved.table$role[1:2], + seq_along(saved.table$givenName)[-(1:2)] + ) + isolate(rv$Personnel <- saved.table) + + sapply(rv$Personnel$id, function(rvid) { + rv <- insertPersonnelInput( + rvid, + rv, + ns, + main.env, + role = if (rvid %in% c("creator", "contact")) rvid, + saved = saved.table + ) + return() + }) + } else { # New rv <- insertPersonnelInput( - rvid, + "creator", rv, ns, main.env, - role = if (rvid %in% c("creator", "contact")) rvid, + role = "creator", + saved = saved.table + ) + + rv <- insertPersonnelInput( + "contact", + rv, + ns, + main.env, + role = "contact", saved = saved.table ) - return() - }) - } else { # New - rv <- insertPersonnelInput( - "creator", - rv, - ns, - main.env, - role = "creator", - saved = saved.table - ) - - rv <- insertPersonnelInput( - "contact", - rv, - ns, - main.env, - role = "contact", - saved = saved.table - ) - } - - # Fill Personnel ----------------------------------------------------- - observeEvent(input$addui, { - id <- dim(rv$Personnel[-c(1:2), ])[1] + 1 - while (as.character(id) %in% rv$Personnel$id) { - id <- id + 1 } - rv <- insertPersonnelInput( - as.character(id), - rv, - ns, - main.env + + # Fill Personnel ---- + observeEvent(input$addui, { + id <- dim(rv$Personnel[-c(1:2), ])[1] + 1 + while (as.character(id) %in% rv$Personnel$id) { + id <- id + 1 + } + rv <- insertPersonnelInput( + as.character(id), + rv, + ns, + main.env + ) + }) + + # Saves ---- + observe({ + main.env$EAL$completed <- all( + # Personnel + isTruthy(rv$Personnel$givenName) && + isTruthy(rv$Personnel$surName) && + isTruthy(rv$Personnel$organizationName) && + isTruthy(rv$Personnel$electronicMailAddress) && + all(c("creator", "contact") %in% rv$Personnel$role) + ) + }) + + # observeEvent(NSB$SAVE, + shinyjs::onclick( + "fill-wizard-save", + asis = TRUE, + add = TRUE, + { + req(main.env$EAL$current == "Personnel") + + # save + save.variable <- saveReactive( + save.variable = savevar, + rv = list(Personnel = rv) + ) + }, + ignoreInit = TRUE ) - }) - - # Saves ----------------------------------------------------- - observe({ - main.env$EAL$current[2] <- all( - # Personnel - isTruthy(rv$Personnel$givenName) && - isTruthy(rv$Personnel$surName) && - isTruthy(rv$Personnel$organizationName) && - isTruthy(rv$Personnel$electronicMailAddress) && - all(c("creator", "contact") %in% rv$Personnel$role) + + # Process data ---- + observeEvent(EAL$.next, + { + req(checkTruth(rv$Personnel)) + req(main.env$EAL$current == "Personnel") + + save.variable <- saveReactive( + save.variable, + rv = list(Personnel = rv) + ) + }, + priority = 1, + ignoreInit = TRUE ) + + # Output ---- + return(save.variable) }) - - observeEvent(NSB$SAVE, - { - req(main.env$EAL$current[1] == "Personnel") - - # save - save.variable <- saveReactive( - save.variable = savevar, - rv = list(Personnel = rv) - ) - }, - ignoreInit = TRUE - ) - - # Process data ----------------------------------------------------- - observeEvent(NSB$NEXT, - { - req(checkTruth(rv$Personnel)) - req(main.env$EAL$current == "Personnel") - - save.variable <- saveReactive( - save.variable, - rv = list(Personnel = rv) - ) - }, - priority = 1, - ignoreInit = TRUE - ) - - # Output ----------------------------------------------------- - return(save.variable) } #' @import shiny #' #' @noRd insertPersonnelInput <- function(id, rv, ns, main.env, role = NULL, saved = NULL) { - - # initialize IDs ----------------------------------------------------- + + # initialize IDs ---- div.id <- id site.id <- paste0("site_", id) rmv.id <- paste0("rmv_", id) - - # Proper module server ----------------------------------------------------- + + # Proper module server ---- # insert new UI newUI <- PersonnelModUI( ns(id), div.id, site.id, rmv.id, role = role, saved = saved ) insertUI( - selector = paste0("#", ns("inserthere")), + selector = paste0("#", NS(id, "inserthere")), ui = newUI ) - + # create associated server - rv <- callModule( - PersonnelMod, id, # module args + rv <- PersonnelMod( + id, main.env, rv, # reactiveValues rmv.id, site.id, div.id, # renderUI ids role = role, saved = saved # set saved ) - - # Output ----------------------------------------------------- + + # Output ---- return(rv) } @@ -213,30 +210,30 @@ insertPersonnelInput <- function(id, rv, ns, main.env, role = NULL, saved = NULL #' #' @noRd PersonnelModUI <- function(id, div.id, site.id, rmv.id, - role = NULL, saved = NULL) { + role = NULL, saved = NULL) { ns <- NS(id) - + value <- if (checkTruth(saved)) { saved[saved$id == div.id, ] } else { NULL } - + # set Project Information embedding tag .pi.embed <- if (!is.null(role)) { shinyjs::hidden } else { shiny::tagList } - + tags$div( id = site.id, fluidRow( class = "inputBox", - # Form ----------------------------------------------------- + # Form ---- # column(11, tagList( - # * (ORCID) Personnel identification ----------------------------------------------------- + # * (ORCID) Personnel identification ---- fluidRow( class = "topInputRow", column( @@ -245,7 +242,7 @@ PersonnelModUI <- function(id, div.id, site.id, rmv.id, 4, if (is.null(role)) { selectInput( - ns("role"), + NS(id, "role"), c("creator", "PI (principal investigator)", "contact", "(other)"), label = withRedStar("Role"), selected = if (!is.null(value)) { @@ -266,12 +263,12 @@ PersonnelModUI <- function(id, div.id, site.id, rmv.id, 4, shinyjs::hidden( div( - id = ns("role-other"), + id = NS(id, "role-other"), textInput( - ns("role-other"), + NS(id, "role-other"), label = "Title of the custom role", value = if (!is.null(value) && - !value$role %in% c("creator", "PI (principal investigator)", "contact")) { + !value$role %in% c("creator", "PI (principal investigator)", "contact")) { value$role } else { "" @@ -283,7 +280,7 @@ PersonnelModUI <- function(id, div.id, site.id, rmv.id, column( 4, textInput( - ns("userId"), + NS(id, "userId"), label = "ORCID", value = if (!is.null(value)) value$userId else "" ) @@ -301,13 +298,13 @@ PersonnelModUI <- function(id, div.id, site.id, rmv.id, style = "padding-left: 0" ) ), # end of fluidRow 1 - # * Basic identity ----------------------------------------------------- + # * Basic identity ---- fluidRow( style = "padding:5px", column( 4, textInput( - ns("givenName"), + NS(id, "givenName"), label = withRedStar("First name"), value = if (!is.null(value)) value$givenName else "" ) @@ -315,7 +312,7 @@ PersonnelModUI <- function(id, div.id, site.id, rmv.id, column( 4, textInput( - ns("middleInitial"), + NS(id, "middleInitial"), label = "Middle initial", value = if (!is.null(value)) value$middleInitial else "" ) @@ -323,19 +320,19 @@ PersonnelModUI <- function(id, div.id, site.id, rmv.id, column( 4, textInput( - ns("surName"), + NS(id, "surName"), label = withRedStar("Last name"), value = if (!is.null(value)) value$surName else "" ) ) ), # end of fluidRow 1 - # * Contact ----------------------------------------------------- + # * Contact ---- fluidRow( style = "padding:5px", column( 8, textInput( - ns("organizationName"), + NS(id, "organizationName"), label = withRedStar("Name of organization the person is associated with."), value = if (!is.null(value)) value$organizationName else "" ) @@ -343,13 +340,13 @@ PersonnelModUI <- function(id, div.id, site.id, rmv.id, column( 4, textInput( - ns("electronicMailAddress"), + NS(id, "electronicMailAddress"), label = withRedStar("Email address"), value = if (!is.null(value)) value$electronicMailAddress else "" ) ) ), # end of fluidRow 2 - # * Project information ----------------------------------------------------- + # * Project information ---- .pi.embed( div( style = "padding:5px", @@ -358,7 +355,7 @@ PersonnelModUI <- function(id, div.id, site.id, rmv.id, column( 4, textInput( - ns("projectTitle"), + NS(id, "projectTitle"), label = "Project title for this dataset", value = if (!is.null(value)) value$projectTitle else "" ) @@ -366,7 +363,7 @@ PersonnelModUI <- function(id, div.id, site.id, rmv.id, column( 4, textInput( - ns("fundingAgency"), + NS(id, "fundingAgency"), label = "Entity funding the creation of this dataset", value = if (!is.null(value)) value$fundingAgency else "" ) @@ -374,7 +371,7 @@ PersonnelModUI <- function(id, div.id, site.id, rmv.id, column( 4, textInput( - ns("fundingNumber"), + NS(id, "fundingNumber"), label = "Number of the grant or award that supported creation of this dataset", value = if (!is.null(value)) value$fundingNumber else "" ) @@ -393,16 +390,16 @@ PersonnelModUI <- function(id, div.id, site.id, rmv.id, #' #' @noRd PersonnelMod <- function(input, output, session, main.env, - rv, rmv.id, site.id, ref, role = NULL, saved = NULL) { + rv, rmv.id, site.id, ref, role = NULL, saved = NULL) { ns <- session$ns - - # Variable initialization ----------------------------------------------------- + + # Variable initialization ---- if (!is.null(saved)) { value <- saved[saved$id == ref, ] } else { value <- NULL } - + local.rv <- reactiveValues( id = ref, # Basic Identity @@ -421,46 +418,46 @@ PersonnelMod <- function(input, output, session, main.env, fundingAgency = if (!is.null(value)) value$fundingAgency else NA, fundingNumber = if (!is.null(value)) value$fundingNumber else NA ) - - # * Basic Identity ----------------------------------------------------- + + # * Basic Identity ---- name.pattern <- main.env$PATTERNS$name - + observeEvent(input$givenName, { local.rv$givenName <- if (grepl(name.pattern, input$givenName)) { input$givenName } }) - + observeEvent(input$middleInitial, { local.rv$middleInitial <- input$middleInitial }) - + observeEvent(input$surName, { local.rv$surName <- if (grepl(name.pattern, input$surName)) { input$surName } }) - - # * Contact ----------------------------------------------------- + + # * Contact ---- mail.pattern <- main.env$PATTERNS$email - + observeEvent(input$organizationName, { local.rv$organizationName <- input$organizationName }) - + observeEvent(input$electronicMailAddress, { local.rv$electronicMailAddress <- if (grepl(mail.pattern, input$electronicMailAddress)) { input$electronicMailAddress } }) - - # * (ORCID) Personnel identification ----------------------------------------------------- + + # * (ORCID) Personnel identification ---- orcid.pattern <- main.env$PATTERNS$ORCID - + observeEvent(input$userId, { req(input$userId) local.rv$userId <- input$userId - + if (grepl(orcid.pattern, input$userId)) { local.rv$userId <- stringr::str_extract(local.rv$userId, orcid.pattern) updateTextInput( @@ -469,20 +466,20 @@ PersonnelMod <- function(input, output, session, main.env, value = local.rv$userId ) } - + orcid.connect <- try( rorcid::as.orcid( local.rv$userId #TODO ORCID auth % snake ) ) - + if ( grepl(orcid.pattern, input$userId) && isTruthy(orcid.connect) ) { orcid <- local.rv$userId orcid.info <- list() - + # names orcid.info$names <- rorcid::orcid_person(orcid)[[orcid]]$name if (isTruthy(unlist(orcid.info$names$`given-names`$value))) { @@ -493,7 +490,7 @@ PersonnelMod <- function(input, output, session, main.env, local.rv$surName <- orcid.info$names$`family-name`$value updateTextInput(session, "surName", value = local.rv$surName) } - + # organization orcid.info$employment <- rorcid::orcid_employments(orcid)[[orcid]]$`affiliation-group`$summaries[[1]] if (isTruthy(unlist(orcid.info$employment$`employment-summary.organization.name`))) { @@ -501,20 +498,20 @@ PersonnelMod <- function(input, output, session, main.env, updateTextInput(session, "organizationName", value = local.rv$organizationName) } if (is.null(role) && - isTruthy(unlist(orcid.info$employment$`employment-summary.role-title`))) { + isTruthy(unlist(orcid.info$employment$`employment-summary.role-title`))) { local.rv$role <- "(other)" updateTextInput(session, "role", value = local.rv$role) local.rv$`role-other` <- orcid.info$employment$`employment-summary.role-title` updateTextInput(session, "role-other", value = local.rv$`role-other`) } - + # email orcid.info$email <- rorcid::orcid_email(orcid)[[orcid]]$email if (isTruthy(unlist(orcid.info$email$email))) { local.rv$electronicMailAddress <- orcid.info$email$email updateTextInput(session, "electronicMailAddress", value = local.rv$electronicMailAddress) } - + # fundings if (local.rv$role == "PI (principal investigator)") { orcid.info$fundings <- rorcid::orcid_fundings(orcid)[[orcid]]$group$`funding-summary`[[1]] @@ -533,14 +530,14 @@ PersonnelMod <- function(input, output, session, main.env, } } else { showNotification( - id = ns("invalid_userid"), + id = NS(id, "invalid_userid"), "Input 'userId' is not a valid ORCID.", type = "warning" ) } }) - - # * Project information ----------------------------------------------------- + + # * Project information ---- if (is.null(role)) { observeEvent( { @@ -569,19 +566,19 @@ PersonnelMod <- function(input, output, session, main.env, }, ignoreInit = FALSE ) - + observeEvent(input$projectTitle, { if (input$role == "PI (principal investigator)") { local.rv$projectTitle <- input$projectTitle } }) - + observeEvent(input$fundingAgency, { if (input$role == "PI (principal investigator)") { local.rv$fundingAgency <- input$fundingAgency } }) - + observeEvent(input$fundingNumber, { if (input$role == "PI (principal investigator)") { local.rv$fundingNumber <- input$fundingNumber @@ -593,13 +590,13 @@ PersonnelMod <- function(input, output, session, main.env, local.rv$fundingAgency <- "" local.rv$fundingNumber <- "" } - - # Metadata save ----------------------------------------------------- + + # Metadata save ---- observe({ req( !is.null(role) || (any(grepl(rmv.id, names(input))) && - input[[rmv.id]] < 1) + input[[rmv.id]] < 1) ) personnel <- isolate(rv$Personnel) # Fetch correct index @@ -609,26 +606,26 @@ PersonnelMod <- function(input, output, session, main.env, else { dim(personnel)[1] + 1 } - + # print values into rv at selected index .values <- printReactiveValues(local.rv) .values <- .values[colnames(personnel)] .values[which(!sapply(.values, isTruthy))] <- "" isolate(rv$Personnel[ind, ] <- .values) }) - - # Remove UI ----------------------------------------------------- + + # Remove UI ---- if (is.null(role)) { observeEvent(input$rmv.id, { # unload the RV ind <- match(ref, rv$Personnel$id) rv$Personnel <- rv$Personnel %>% slice(-ind) - + # remove the UI removeUI(selector = paste0("#", site.id), immediate = TRUE) }) } - - # Output ----------------------------------------------------- + + # Output ---- return(rv) } diff --git a/R/eal_8_misc.R b/R/eal_8_misc.R index 1731989..74814a4 100644 --- a/R/eal_8_misc.R +++ b/R/eal_8_misc.R @@ -3,20 +3,25 @@ #' @importFrom data.table fread #' #' @noRd -MiscUI <- function(id, title, dev, save.variable) { +MiscUI <- function(id, main.env) { ns <- NS(id) - - keywords <- fread( - paste0(save.variable$emlal$SelectDP$dp.metadata.path, "/keywords.txt"), - data.table = FALSE, stringsAsFactors = FALSE - ) + + .metadata.path <- isolate(main.env$save.variable$emlal$SelectDP$dp.metadata.path) + + if(file.exists(paste0(.metadata.path, "/keywords.txt"))) + keywords <- data.table::fread( + paste0(.metadata.path, "/keywords.txt"), + data.table = FALSE, stringsAsFactors = FALSE + ) + else + keywords <- "" if (checkTruth(keywords)) { kw <- keywords$keyword %>% strsplit(split = ",") %>% unlist %>% paste(collapse = ",") } - + return( fluidPage( fluidRow( @@ -28,33 +33,35 @@ MiscUI <- function(id, title, dev, save.variable) { "), bsCollapse( - id = ns("Miscs"), - - # * Abstract ----------------------------------------------------- + id = NS(id, "Miscs"), + + # * Abstract ---- bsCollapsePanel( title = withRedStar("Abstract"), value = 1, MiscellaneousUI( - ns("abstract"), - value = readPlainText( - paste0(save.variable$emlal$SelectDP$dp.metadata.path, "/abstract.txt") - ) + NS(id, "abstract"), + value = if(file.exists(paste0(.metadata.path, "/abstract.txt"))) + readPlainText( + paste0(.metadata.path, "/abstract.txt") + ) ) ), - - # * Methods ----------------------------------------------------- + + # * Methods ---- bsCollapsePanel( title = withRedStar("Methods"), value = 2, MiscellaneousUI( - ns("methods"), - value = readPlainText( - paste0(save.variable$emlal$SelectDP$dp.metadata.path, "/methods.txt") - ) + NS(id, "methods"), + value = if(file.exists(paste0(.metadata.path, "/methods.txt"))) + readPlainText( + paste0(.metadata.path, "/methods.txt") + ) ) ), - - # * Keywords ----------------------------------------------------- + + # * Keywords ---- bsCollapsePanel( title = withRedStar("Keywords"), value = 3, @@ -62,7 +69,7 @@ MiscUI <- function(id, title, dev, save.variable) { column( 6, tagsinput::tagsTextInput( - ns("keywords"), + NS(id, "keywords"), tags$p("List the keywords that best describe your dataset. Type a 'tab' to separate each keyword."), value = if (checkTruth(keywords)) keywords[, 1] else c() @@ -75,12 +82,12 @@ MiscUI <- function(id, title, dev, save.variable) { no control is made about thesaurus input field and this can be invalided."), tags$p("You may associate a thesaurus to each keyword."), - uiOutput(ns("thesaurus")) + uiOutput(NS(id, "thesaurus")) ) ) ), - - # * Temporal coverage ----------------------------------------------------- + + # * Temporal coverage ---- bsCollapsePanel( title = "Temporal coverage", value = 4, @@ -88,7 +95,7 @@ MiscUI <- function(id, title, dev, save.variable) { column(10, offset = 1, dateRangeInput( - ns("temporal_coverage"), + NS(id, "temporal_coverage"), "Dates between which dataset's content was produced", max = Sys.Date(), autoclose = FALSE @@ -96,19 +103,20 @@ MiscUI <- function(id, title, dev, save.variable) { ) ) ), - - # * Additional Info ----------------------------------------------------- + + # * Additional Info ---- bsCollapsePanel( title = "Additional Info", value = 5, MiscellaneousUI( - ns("additional.information"), + NS(id, "additional.information"), help.label = tags$p( "If you have additional information that doesn't fall under the scope of the abstract or methods (e.g. a list of research articles or theses derived from this dataset) about your dataset, you may share it here." ), - value = readPlainText( - paste0(save.variable$emlal$SelectDP$dp.metadata.path, "/additional_info.txt") - ) + value = if(file.exists(paste0(.metadata.path, "/additional_info.txt"))) + readPlainText( + paste0(.metadata.path, "/additional_info.txt") + ) ) ) ) @@ -123,176 +131,170 @@ MiscUI <- function(id, title, dev, save.variable) { #' @importFrom data.table fread #' #' @noRd -Misc <- function(input, output, session, save.variable, main.env, NSB) { - ns <- session$ns - - if (main.env$DEV) { - shinyjs::onclick("dev", - { - req(main.env$EAL$navigate == 8) - browser() - }, - asis = TRUE +Misc <- function(id, main.env) { + moduleServer(id, function(input, output, session){ + save.variable <- main.env$save.variable + ns <- session$ns + + # Variable initialization ---- + kw <- fread( + paste0(save.variable$emlal$SelectDP$dp.metadata.path, "/keywords.txt"), + data.table = FALSE, stringsAsFactors = FALSE ) - } - - # Variable initialization ----------------------------------------------------- - kw <- fread( - paste0(save.variable$emlal$SelectDP$dp.metadata.path, "/keywords.txt"), - data.table = FALSE, stringsAsFactors = FALSE - ) - - rv <- reactiveValues( - # Abstract - abstract = reactiveValues( - content = character(), - file = paste( - isolate(save.variable$emlal$SelectDP$dp.metadata.path), - "abstract.txt", - sep = "/" - ) - ), - # Methods - methods = reactiveValues( - content = character(), - file = paste( - isolate(save.variable$emlal$SelectDP$dp.metadata.path), - "methods.txt", - sep = "/" - ) - ), - # Keywords - keywords = reactiveValues( - keyword = kw$keyword, - keyword.thesaurus = kw$keyword.thesaurus - ), - # Temporal coverage - temporal.coverage = c(Sys.Date() - 1, Sys.Date()), - # Additional information - additional.information = reactiveValues( - content = character(), - file = paste( - isolate(save.variable$emlal$SelectDP$dp.metadata.path), - "additional_info.txt", - sep = "/" + + rv <- reactiveValues( + # Abstract + abstract = reactiveValues( + content = character(), + file = paste( + isolate(save.variable$emlal$SelectDP$dp.metadata.path), + "abstract.txt", + sep = "/" + ) + ), + # Methods + methods = reactiveValues( + content = character(), + file = paste( + isolate(save.variable$emlal$SelectDP$dp.metadata.path), + "methods.txt", + sep = "/" + ) + ), + # Keywords + keywords = reactiveValues( + keyword = kw$keyword, + keyword.thesaurus = kw$keyword.thesaurus + ), + # Temporal coverage + temporal.coverage = c(Sys.Date() - 1, Sys.Date()), + # Additional information + additional.information = reactiveValues( + content = character(), + file = paste( + isolate(save.variable$emlal$SelectDP$dp.metadata.path), + "additional_info.txt", + sep = "/" + ) ) ) - ) - - # Fill ----------------------------------------------------- - # * Abstract ==== - rv$abstract <- callModule( - Miscellaneous, - "abstract", - save.variable, - rv = rv$abstract - ) - - # * Methods ==== - rv$methods <- callModule( - Miscellaneous, - "methods", - save.variable, - rv = rv$methods - ) - - # * Keywords ==== - observeEvent(input$keywords, { - req(input$keywords) - - rv$keywords$keyword <- unique(input$keywords) - - output$thesaurus <- renderUI({ + + # Fill ---- + # * Abstract ==== + rv$abstract <- Miscellaneous( + "abstract", + save.variable, + rv = rv$abstract + ) + + # * Methods ==== + rv$methods <- Miscellaneous( + "methods", + save.variable, + rv = rv$methods + ) + + # * Keywords ==== + observeEvent(input$keywords, { + req(input$keywords) + + rv$keywords$keyword <- unique(input$keywords) + + output$thesaurus <- renderUI({ + validate( + need(checkTruth(rv$keywords$keyword), "No keyword input") + ) + tagList( + lapply(seq_along(rv$keywords$keyword), function(kid) { + keyword <- rv$keywords$keyword[kid] + .val <- rv$keywords$keyword.thesaurus[kid] + + textInput( + ns(paste0("thesaurus-for-", keyword)), + keyword, + value = if (isTruthy(.val)) .val else "" + ) + }) + ) + }) + }) + + # NOTE observers are still active after being deleted + observe({ validate( - need(checkTruth(rv$keywords$keyword), "No keyword input") + need(rv$keywords$keyword, "No keyword input") ) - tagList( - lapply(seq_along(rv$keywords$keyword), function(kid) { - keyword <- rv$keywords$keyword[kid] - .val <- rv$keywords$keyword.thesaurus[kid] - - textInput( - ns(paste0("thesaurus-for-", keyword)), - keyword, - value = if (isTruthy(.val)) .val else "" - ) - }) + sapply(seq_along(rv$keywords$keyword), function(kid) { + keyword <- rv$keywords$keyword[kid] + input_id <- paste0("thesaurus-for-", keyword) + .val <- if (isTruthy(input[[input_id]])) input[[input_id]] else "" + + rv$keywords$keyword.thesaurus[kid] <- .val + }) + }) + + # * Temporal coverage ==== + if (!is.null(save.variable$emlal$Misc$temporal.coverage)) { + rv$temporal.coverage <- save.variable$emlal$Misc$temporal.coverage + updateDateRangeInput( + session, + "temporal.coverage", + start = rv$temporal.coverage[1], + end = rv$temporal.coverage[2] ) + } + observeEvent(input$temporal_coverage, { + rv$temporal.coverage <- input$temporal_coverage }) - }) - - # NOTE observers are still active after being deleted - observe({ - validate( - need(rv$keywords$keyword, "No keyword input") + + # * Additional information ==== + rv$additional.information <- Miscellaneous( + "additional.information", + save.variable, + rv = rv$additional.information ) - sapply(seq_along(rv$keywords$keyword), function(kid) { - keyword <- rv$keywords$keyword[kid] - input_id <- paste0("thesaurus-for-", keyword) - .val <- if (isTruthy(input[[input_id]])) input[[input_id]] else "" - - rv$keywords$keyword.thesaurus[kid] <- .val + + # Saves ---- + observe({ + main.env$EAL$completed <- all( + isTruthy(rv$abstract$content()) && + isTruthy(rv$methods$content()) && + isTruthy(rv$keywords$keyword) && + isTruthy(rv$temporal.coverage) + ) }) - }) - - # * Temporal coverage ==== - if (!is.null(save.variable$emlal$Misc$temporal.coverage)) { - rv$temporal.coverage <- save.variable$emlal$Misc$temporal.coverage - updateDateRangeInput( - session, - "temporal.coverage", - start = rv$temporal.coverage[1], - end = rv$temporal.coverage[2] + + # observeEvent(NSB$SAVE, + shinyjs::onclick( + "fill-wizard-save", + asis = TRUE, + add = TRUE, + { + req(main.env$EAL$current == "Miscellaneous") + + save.variable <- saveReactive( + save.variable = savevar, + rv = list(Misc = rv) + ) + }, + ignoreInit = TRUE ) - } - observeEvent(input$temporal_coverage, { - rv$temporal.coverage <- input$temporal_coverage - }) - - # * Additional information ==== - rv$additional.information <- callModule( - Miscellaneous, - "additional.information", - save.variable, - rv = rv$additional.information - ) - - # Saves ----------------------------------------------------- - observe({ - main.env$EAL$current[2] <- all( - isTruthy(rv$abstract$content()) && - isTruthy(rv$methods$content()) && - isTruthy(rv$keywords$keyword) && - isTruthy(rv$temporal.coverage) + + # Process data ---- + observeEvent(EAL$.next, + { + req(main.env$EAL$current == "Miscellaneous") + + save.variable <- saveReactive( + save.variable = savevar, + rv = list(Misc = rv) + ) + }, + priority = 1, + ignoreInit = TRUE ) + + # Output ---- + return(save.variable) }) - - observeEvent(NSB$SAVE, - { - req(main.env$EAL$current[1] == "Miscellaneous") - - save.variable <- saveReactive( - save.variable = savevar, - rv = list(Misc = rv) - ) - }, - ignoreInit = TRUE - ) - - # Process data ----------------------------------------------------- - observeEvent(NSB$NEXT, - { - req(main.env$EAL$current[1] == "Miscellaneous") - - save.variable <- saveReactive( - save.variable = savevar, - rv = list(Misc = rv) - ) - }, - priority = 1, - ignoreInit = TRUE - ) - - # Output ----------------------------------------------------- - return(save.variable) } diff --git a/R/eal_8_miscellaneous.R b/R/eal_8_miscellaneous.R index bf5d61b..bb5039f 100644 --- a/R/eal_8_miscellaneous.R +++ b/R/eal_8_miscellaneous.R @@ -3,7 +3,6 @@ #' #' @noRd MiscellaneousUI <- function(id, help.label = NULL, value = "") { - ns <- NS(id) fluidRow( # file selection @@ -13,13 +12,13 @@ MiscellaneousUI <- function(id, help.label = NULL, value = "") { tags$br(), div( fileInput( - ns("file"), + NS(id, "file"), "", multiple = FALSE, buttonLabel = span("Load file", icon("file")), ) ), - div(textOutput(ns("selected")), class = "ellipsis") + div(textOutput(NS(id, "selected")), class = "ellipsis") ), # Content edition column( @@ -28,7 +27,7 @@ MiscellaneousUI <- function(id, help.label = NULL, value = "") { tags$b("Content"), help.label, markdownInputUI( - ns("content"), + NS(id, "content"), label = "", value = value, preview = FALSE @@ -43,13 +42,13 @@ MiscellaneousUI <- function(id, help.label = NULL, value = "") { #' #' @noRd Miscellaneous <- function(input, output, session, save.variable, rv) { - # Variable initialization ----------------------------------------------------- + # Variable initialization ---- ns <- session$ns - # Get content ----------------------------------------------------- - rv$content <- callModule(markdownInput, "content", preview = FALSE) + # Get content ---- + rv$content <- markdownInput("content", preview = FALSE) - # Get file ----------------------------------------------------- + # Get file ---- observeEvent(input$file, { req(input$file) @@ -81,6 +80,6 @@ Miscellaneous <- function(input, output, session, save.variable, rv) { ) }) - # Output ----------------------------------------------------- + # Output ---- return(rv) } diff --git a/R/eal_9_annotations.R b/R/eal_9_annotations.R index 7acd290..e2a560a 100644 --- a/R/eal_9_annotations.R +++ b/R/eal_9_annotations.R @@ -6,7 +6,7 @@ #' useShinyjs(), #' tags$div( #' tags$br(), -#' actionButton(ns("addui"), "", icon("plus")), +#' actionButton(NS(id, "addui"), "", icon("plus")), #' fluidRow( #' column(11, #' column(4, "Subject"), @@ -15,8 +15,8 @@ #' ), #' style = "background-color: white; text-align: center" #' ), -#' uiOutput(ns("annotation_fields")), -#' tags$div(id = ns("inserthere")), +#' uiOutput(NS(id, "annotation_fields")), +#' tags$div(id = NS(id, "inserthere")), #' tags$br(), #' class = "inputBox wip" #' ) # end of fluidPage @@ -64,7 +64,7 @@ #' footer = tagList( #' modalButton("Cancel"), #' actionButton( -#' ns("insert"), +#' NS(id, "insert"), #' "New annotation" #' ) %>% disabled #' ) @@ -95,19 +95,19 @@ #' #' @import shiny #' insertAnnotInput <- function(id, rv, ns, main.env, value = NULL) { #' -#' # initialize IDs ----------------------------------------------------- +#' # initialize IDs ---- #' div_id <- id #' site_id <- paste0("site_", id) #' rmv_id <- paste0("rmv_", id) #' -#' # Proper module server ----------------------------------------------------- +#' # Proper module server ---- #' # insert new UI #' newUI <- AnnotModUI( #' ns(id), div_id, site_id, rmv_id, #' value = value #' ) #' insertUI( -#' selector = paste0("#", ns("inserthere")), +#' selector = paste0("#", NS(id, "inserthere")), #' ui = newUI #' ) #' @@ -119,7 +119,7 @@ #' value = value # set saved #' ) #' -#' # Output ----------------------------------------------------- +#' # Output ---- #' return(rv) #' } #' @@ -187,7 +187,7 @@ #' rv, rmv_id, site_id, ref, role = NULL, saved = NULL) { #' ns <- session$ns #' -#' # Variable initialization ----------------------------------------------------- +#' # Variable initialization ---- #' if(!is.null(saved)){ #' value <- saved[saved$id == ref,] #' } else { @@ -225,7 +225,7 @@ #' local.rv <- ontoloGUI("object", local.rv) #' }) #' -#' # Metadata save ----------------------------------------------------- +#' # Metadata save ---- #' observe({ #' req( #' !is.null(value) || @@ -259,6 +259,6 @@ #' removeUI(selector = paste0("#", site_id), immediate = TRUE) #' }) #' -#' # Output ----------------------------------------------------- +#' # Output ---- #' return(rv) #' } \ No newline at end of file diff --git a/R/eal_9_makeeml.R b/R/eal_9_makeeml.R index 8f6b02b..b177ad5 100644 --- a/R/eal_9_makeeml.R +++ b/R/eal_9_makeeml.R @@ -2,9 +2,9 @@ #' @importFrom shinyjs hidden disabled #' #' @noRd -MakeEMLUI <- function(id, title, dev) { +MakeEMLUI <- function(id, main.env) { ns <- NS(id) - + return( fluidPage( fluidRow( @@ -14,15 +14,15 @@ MakeEMLUI <- function(id, title, dev) { a EML-valid xml file."), tags$p("(NOTE: you will be able to edit this data package furtherly)"), actionButton( - ns("make_eml"), + NS(id, "make_eml"), "Make EML", icon("edit"), width = "50%" ), - textOutput(ns("warnings")), + textOutput(NS(id, "warnings")), shinyjs::hidden( actionLink( - ns("bug_report"), + NS(id, "bug_report"), span("Please report this to the dev", icon("external-link-alt")) ) ), @@ -42,7 +42,7 @@ MakeEMLUI <- function(id, title, dev) { tags$b("Generate a summary of your data package."), tags$i("(clicking on the below button will open a preview)"), downloadButton( - ns("download_emldown"), + NS(id, "download_emldown"), "Download emldown", width = "50%" ) @@ -59,168 +59,161 @@ MakeEMLUI <- function(id, title, dev) { #' @importFrom emldown render_eml #' #' @noRd -MakeEML <- function(input, output, session, save.variable, main.env) { - ns <- session$ns - - if (main.env$DEV) { - shinyjs::onclick("dev", - { - req(main.env$EAL$navigate == 9) - browser() - }, - asis = TRUE +MakeEML <- function(id, main.env) { + moduleServer(id, function(input, output, session){ + save.variable <- main.env$save.variable + ns <- session$ns + + # Variable initialization ---- + out.file <- paste0( + save.variable$emlal$SelectDP$dp.path, + "/emldown/emldown.html" ) - } - - # Variable initialization ----------------------------------------------------- - out.file <- paste0( - save.variable$emlal$SelectDP$dp.path, - "/emldown/emldown.html" - ) - - # Make eml ----------------------------------------------------- - observeEvent(input$make_eml, { - shinyjs::hide("bug_report") - req(input$make_eml) - withProgress( - { - . <- save.variable$emlal - fileName <- .$SelectDP$dp_title - - x <- try( - EMLassemblyline::template_arguments( - path = .$SelectDP$dp_metadata_path, - data.path = .$SelectDP$dp_data_path, - data.table = dir(.$SelectDP$dp_data_path) - ) - ) - - if (class(x) == "try-error") { - out <- x - out[1] <- paste("Upon templating arguments:", x) - incProgress(0.9) - } else { - incProgress(0.3) - - x$path <- .$SelectDP$dp_metadata_path - x$data.path <- .$SelectDP$dp_data_path - x$eml.path <- .$SelectDP$dp_eml_path - x$data.table <- dir(x$data.path) - x$data.table.name <- .$DataFiles$table_name - x$data.table.description <- .$DataFiles$description - x$dataset.title <- .$SelectDP$dp_title - x$maintenance.description <- "Ongoing" - # TODO better package.id - x$package.id <- fileName - x$return.obj <- TRUE - x$temporal.coverage <- .$Misc$temporal_coverage - # TODO user domain (pndb?) - x$user.domain <- "UserDomain" - # TODO user id (orcid?) - x$user.id <- "UserID" - x$write.file <- TRUE - - # Yet written in the files then used in make_eml - x$geographic.coordinates <- NULL - x$geographic.description <- NULL - - incProgress(0.2) - - .test <- 0 - out <- try( - do.call( - EMLassemblyline::make_eml, - x[names(x) %in% names(formals(make_eml))] + + # Make eml ---- + observeEvent(input$make_eml, { + shinyjs::hide("bug_report") + req(input$make_eml) + withProgress( + { + . <- save.variable$emlal + fileName <- .$SelectDP$dp_title + + x <- try( + EMLassemblyline::template_arguments( + path = .$SelectDP$dp_metadata_path, + data.path = .$SelectDP$dp_data_path, + data.table = dir(.$SelectDP$dp_data_path) ) ) - if (class(out) == "try-error") { - out[1] <- paste("Upon writing EML:", out) + + if (class(x) == "try-error") { + out <- x + out[1] <- paste("Upon templating arguments:", x) + incProgress(0.9) + } else { + incProgress(0.3) + + x$path <- .$SelectDP$dp_metadata_path + x$data.path <- .$SelectDP$dp_data_path + x$eml.path <- .$SelectDP$dp_eml_path + x$data.table <- dir(x$data.path) + x$data.table.name <- .$DataFiles$table_name + x$data.table.description <- .$DataFiles$description + x$dataset.title <- .$SelectDP$dp_title + x$maintenance.description <- "Ongoing" + # TODO better package.id + x$package.id <- fileName + x$return.obj <- TRUE + x$temporal.coverage <- .$Misc$temporal_coverage + # TODO user domain (pndb?) + x$user.domain <- "UserDomain" + # TODO user id (orcid?) + x$user.id <- "UserID" + x$write.file <- TRUE + + # Yet written in the files then used in make_eml + x$geographic.coordinates <- NULL + x$geographic.description <- NULL + + incProgress(0.2) + + .test <- 0 + out <- try( + do.call( + EMLassemblyline::make_eml, + x[names(x) %in% names(formals(make_eml))] + ) + ) + if (class(out) == "try-error") { + out[1] <- paste("Upon writing EML:", out) + } + incProgress(0.4) } - incProgress(0.4) - } - }, - message = "Writing EML ...", - value = 0.1 - ) - - valid.eml <- EML::eml_validate( - dir( - save.variable$emlal$SelectDP$dp.eml.path, - full.names = TRUE + }, + message = "Writing EML ...", + value = 0.1 ) - ) - - output$warnings <- renderText({ - disable("publish") - disable("emldown") - validate( - need( - class(out) != "try-error", - out[1] - ), - need( - !isFALSE(valid.eml), - unique(attr(valid.eml, "errors")) + + valid.eml <- EML::eml_validate( + dir( + save.variable$emlal$SelectDP$dp.eml.path, + full.names = TRUE ) ) - shinyjs::enable("publish") - shinyjs::enable("emldown") - return(NULL) - }) - - if (class(out) == "try-error" || - isFALSE(valid.eml)) { - shinyjs::show("bug_report") - showNotification("EML invalid", type = "error", duration = NULL) - } else { - shinyjs::hide("bug_report") - showNotification("EML written.", type = "message") - # emldown - eml.file <- dir( - save.variable$emlal$SelectDP$dp.eml.path, - full.names = TRUE, - pattern = save.variable$emlal$SelectDP$dp.title - ) - dir.create(dirname(out.file), recursive = TRUE) - old.wd <- getwd() - setwd(dirname(out.file)) - out <- emldown::render_eml( - file = eml.file, - open = TRUE, - out.file = out.file, - publish_mode = TRUE - ) - setwd(old.wd) - if (file.exists(out.file)) { - showNotification("emldown generated", type = "message") + output$warnings <- renderText({ + disable("publish") + disable("emldown") + validate( + need( + class(out) != "try-error", + out[1] + ), + need( + !isFALSE(valid.eml), + unique(attr(valid.eml, "errors")) + ) + ) + shinyjs::enable("publish") + shinyjs::enable("emldown") + return(NULL) + }) + + if (class(out) == "try-error" || + isFALSE(valid.eml)) { + shinyjs::show("bug_report") + showNotification("EML invalid", type = "error", duration = NULL) + } else { + shinyjs::hide("bug_report") + showNotification("EML written.", type = "message") + + # emldown + eml.file <- dir( + save.variable$emlal$SelectDP$dp.eml.path, + full.names = TRUE, + pattern = save.variable$emlal$SelectDP$dp.title + ) + dir.create(dirname(out.file), recursive = TRUE) + old.wd <- getwd() + setwd(dirname(out.file)) + out <- emldown::render_eml( + file = eml.file, + open = TRUE, + out.file = out.file, + publish_mode = TRUE + ) + setwd(old.wd) + if (file.exists(out.file)) { + showNotification("emldown generated", type = "message") + } } - } - }) - - observeEvent(input$bug_report, { - utils::browseURL("https://github.com/earnaud/MetaShARK-v2/issues/26") - }) - - # emldown ----------------------------------------------------- - output$download_emldown <- downloadHandler( - filename = function() { - paste( - save.variable$emlal$SelectDP$dp.name, - "_emldown.zip" - ) - }, - content = function(file) { - utils::zip( - zipfile = file, - files = dir( - dirname(out.file), - recursive = TRUE + }) + + observeEvent(input$bug_report, { + utils::browseURL("https://github.com/earnaud/MetaShARK-v2/issues/26") + }) + + # emldown ---- + output$download_emldown <- downloadHandler( + filename = function() { + paste( + save.variable$emlal$SelectDP$dp.name, + "_emldown.zip" ) - ) - } - ) - - # Output ----------------------------------------------------- - return(save.variable) + }, + content = function(file) { + utils::zip( + zipfile = file, + files = dir( + dirname(out.file), + recursive = TRUE + ) + ) + } + ) + + # Output ---- + return(save.variable) + }) } diff --git a/R/fill-module.R b/R/fill-module.R index d1ebfdd..8643994 100644 --- a/R/fill-module.R +++ b/R/fill-module.R @@ -1,31 +1,265 @@ #' @import shiny #' #' @noRd -fillUI <- function(id, dev = FALSE) { +fillUI <- function(id, main.env) { ns <- NS(id) + tabsetPanel( - id = ns("tabs"), - tabPanel("EAL", EMLALUI(ns("EAL"), dev)), - tabPanel("MetaFIN", h1("Under Construction")) + id = NS(id, "tabs"), + tabPanel("EAL", + # EMLALUI(NS(id, "EAL"), main.env) + fluidPage( + style = "padding-top:2.5%;", + pagesUI( + NS(id, "wizard"), + parent.id = id, + main.env = main.env + ) + ) # end fluidPage + ), + tabPanel( + "MetaFIN", + tags$h1("Under Construction"), + tags$img(src = "media/working.png") + ) ) } #' @import shiny #' #' @noRd -fill <- function(input, output, session, main.env) { - ns <- session$ns - # variable initialization ==== - - # save variable initialization - save.variable <- initReactive(main.env = main.env$EAL) - - # action ==== - save.variable <- callModule( - EMLAL, "EAL", - save.variable, main.env - ) - - # Output ==== - return(save.variable) +fill <- function(id, main.env){ + moduleServer(id, function(input, output, session) { + # Variable initialization ==== + .EAL <- main.env$EAL # local copy + save.variable <- main.env$save.variable + steps <- isolate(main.env$VALUES$steps) + + # Wizard ==== + + # pages change + pagesServer(NS(id, "wizard"), steps) + + # modules content + SelectDP("SelectDP", main.env) + DataFiles("DataFiles", main.env) + Attributes("Attributes", main.env) + CatVars("CatVars", main.env) + GeoCov("GeoCov", main.env) + TaxCov("TaxCov", main.env) + Personnel("Personnel", main.env) + Misc("Misc", main.env) + MakeEML("MakeEML", main.env) + + # Navigation ---- + observeEvent(.EAL$page, { + # set EAL variables + if(identical(.EAL$history, character())){ + .EAL$history <- main.env$VALUES$steps[1:.EAL$page] + .EAL$current <- main.env$VALUES$steps[.EAL$page] + } + + # On loading DP, correct step + isolate({ + if(.EAL$page == -1) + .EAL$page <- match( + utils::tail(save.variable$emlal$history,1), + steps + ) + }) + + if (.EAL$current == "Data Files") { + unlink(main.env$PATHS$eal.tmp) + } + file.remove( + list.files( + save.variable$emlal$SelectDP$dp.data.path, + pattern = "preview___" + ) + ) + .EAL$current <- main.env$VALUES$steps[.EAL$page] + if (.EAL$current == "Data Files" && + !dir.exists(main.env$PATHS$eal.tmp)) { + dir.create(main.env$PATHS$eal.tmp) + } + + if (isFALSE(.EAL$completed)) { + .EAL$completed <- TRUE + } # trigger + .EAL$completed <- FALSE + EAL$tag.list <- tagList() + + # Edition changed path -> remove excedent history + if (!.EAL$current %in% .EAL$history) { + .EAL$history <- c(.EAL$history, .EAL$current) + } + + # Savevar modification + save.variable$emlal$step <- .EAL$page + save.variable$emlal$history <- .EAL$history + + updateTabsetPanel(session, "wizard", selected = steps[to]) + + # Modules helper ---- + NSB$help <- modalDialog( + title = paste0(.EAL$current, " - Help"), + switch(.EAL$page, + # SelectDP + tagList( + tags$p("This module allows you to manage your", tags$strong("data packages"), ". + A data package (aka DP) is a collection of a dataset and its associated metadata + and resources (scripts, literature, ...). You can:"), + tags$ul( + tags$li("Load an existing data package among local ones (left). You + will resume its edition at the last saved encountered step."), + tags$li( + "Create a new data package. You must fill in", tags$strong("three fields"), + tags$i("Data package name"), "will be used for identifying the DP,", + tags$i("Data package title"), "will be displayed when consulting the DP + page once formatted (explained in last step),", + tags$i("Data package license"), "is the license assigned to this production for + intellectual rights properties" + ) + ), + tags$p("Also, notice the", tags$strong("quick"), "check box above DP name. + Checking this box enables \"quick mode\" which will pre-fill most of the + fields in further steps. You still will be able to edit them at your + convenience.") + ), + # Data Files + tagList( + tags$p("This module allows you to load data files from the dataset you want to + describe. Once uploaded, you can set:"), + tags$ul( + tags$li(tags$i("Content name:"), "A name for the data contained in the file (e.g. table name)."), + tags$li(tags$i("URL:"), "If the file is accessible remotely, here is a way to reference it."), + tags$li(tags$i("Description:"), "A short text provided to describe the file, its content, + relevant information about the data in the entity.") + ), + tags$p("To edit your selection, select files among the list with the check boxes on + their left, then click the \"Remove\" button."), + tags$p("Recommended size per file is around 1 Gb. Such files and heavier ones might slow down the + app.") + ), + # Attributes + tagList( + tags$p("This module allows you to describe precisely each attribute of each file. Some of these metadata + are guessed from the data files. Such fields are annoted with a star (*). + For each attribute, you can set:"), + tags$ul( + tags$li(tags$i("Attribute Name*:"), "the name of the attribute."), + tags$li(tags$i("Attribute Description:"), "a "), + tags$li(tags$i("Attribute Class*:"), "the type of content in the attributes among + \"numeric\", \"character\", \"categorical\" and \"Date\". Categorical means a + character string with encoded values (e.g. Male/Female)."), + tags$li(tags$i("Date format (only for Date class): how the dates of the attributes are + written (e.g. DD-MM-YYYY).")), + tags$li(tags$i("Unit (only for Numeric class):"), "which is the unit used for the + numeric data of the attributes. The list is huge and refers to", tags$a("STMML Scientific + units", href = "http://www.ch.ic.ac.uk/rzepa/codata2/"), ". You can also define you own unit + (see Custom Units thereafter)."), + tags$li(tags$i("Missing Value Code:"), "a one-word code used instead of a missing value among + the data of the attribute currently described."), + tags$li(tags$i("Missing Value Code Explanation:"), "a short definition of the meaning(s) given + for the missing value code.") + ), + tags$h3("Custom units creation"), + tags$p("EML allows the user to define its own units, but this require to fulfill some more + fields. However, the custom units you will have defined will be saved into the Custom Units + table at the bottom of this page. You will find the written custom units in the units selection + once they are written. To define a custom unit, chose the unit to be \"custom\". A custom + unit is defined with:"), + tags$ul( + tags$li(tags$i("Unit id:"), "the id of the unit (e.g. gramsPerOneThirdMeter). The unit id + must validate the STMML schema."), + tags$li(tags$i("Unit type:"), "the physical property measured by the custom unit (e.g. mass)."), + tags$li(tags$i("Parent unit in SI:"), "from which unit among the most common one is the custom + unit derived (e.g. gram)."), + tags$li(tags$i("Multiplier to SI:"), "by how many has the custom unit to be multiplied to be + equal to its parent unit."), + tags$li(tags$i("Unit description:"), "some additional notes about the unit, how to compute it.") + ) + ), + # Catvars + tagList( + tags$p("This module allows you to detail the categorical variables (class \"categorical\" in Attributes). + For each variable, you will be able to detail each of its value by a short description.") + ), + # Geocov + tagList( + tags$p("This module allows you to define the geographic area in which the data have been produced. + You have the choice between two methods to define geographic coverage:"), + tags$ul( + tags$li( + tags$h4("Columns description (recommended)"), + tags$p("This method asks you to choose columns in one of your files. For latitude and longitude, + you can select either one or two columns. If a single column contains a pair of numbers, they + will be detected. Chosing single coordinates will be considered as single sites. Chosing pairs of + coordinates will be considered as sub-areas. For each coordinate, you can select a column + containing description for each one.") + ), + tags$li( + tags$h4("Custom description"), + tags$p("With this, you will be able to define by hand each one of the sites covered by your data.") + ) + ) + ), + # Taxcov + tagList( + tags$p("This module allows you to define the taxonomical coverage of the study. You will be asked to + select columns among your files containing the species name. Also, let the app know if the taxonomic + coverage shall be written with scientific, common or both names. At last, select at least one taxonomic + authority among the ones suggested."), + ), + # Personnel + tagList( + tags$p("This module allows you to get a full list of the people who contributed to the creation of + this dataset. The recommended best practice is to", tags$b("use the ORCID"), "of a person. With + this and the help of {rorcid}, the app will be able to fetch all available and interesting data. + You will be able to correct this afterwards. Also, note that you must fill in the fields + for two roles: creator and contact."), + tags$p("Suggested roles are the following:"), + tags$ul( + tags$li("Creator: person who contributed to produce the data."), + tags$li("Contact: persone to contact for any question about the data."), + tags$li("Principal investigator: person who led the creation of the dataset. Selecting this will allow + you to fill in additional information about the project and its funding."), + tags$li("Custom: as the list of roles is not exhaustive, feel free to add any role you consider important.") + ) + ), + # Misc + tagList( + tags$p("This module allows you to define the last details of your data package. Note that you can write + some of these metadata using the markdown syntax. Here are brief descriptions of the fields:"), + tags$ul( + tags$li("Abstract: the abstract of the publication linked to those data."), + tags$li("Methods: the methods used in the production of this dataset."), + tags$li( + "Keywords: you can type a list of keywords for your dataset. For each keyword, you can add a + keyword thesaurus, like", tags$a("the LTER controlled vocabulary ", href = "http://vocab.lternet.edu/vocab/vocab/index.php"), + ", which are controlled vocabulary your exact keyword originates from. Keywords thesaurus are not + required." + ), + tags$li("Temporal coverage: this lets you define the duration of the study during which the data have been produced."), + tags$li("Additional information: if any information has been omitted, you can provide it here (e.g. collection metadata + from GBIF-EML).") + ) + ), + # Make EML + tagList( + tags$p("Here we are (well done) ! This is the final step to write EML. Just click the button and let the magic happen. If an + error occurs, this will be displayed to the screen. In this case, do not hesitate to get in touch with the dev team."), + tags$p("You can also use the {emldown} package to get a human-readable version of the generated EML. The button below it will + let you download the result of this step.") + ) + ), + footer = modalButton("Close"), + easyClose = TRUE, fade = TRUE + ) + }, + label = "EAL0 update" + ) + # Output ==== + return(save.variable) + }) } diff --git a/R/fill_pages.R b/R/fill_pages.R new file mode 100644 index 0000000..95ff7fb --- /dev/null +++ b/R/fill_pages.R @@ -0,0 +1,341 @@ +# UI ==== + +#' @noRd +#' +#' @import shiny +tabPage <- function(title, ui, navTagList = NULL){ + tabPanelBody( + value = title, + tags$span( + div("EML Assembly Line", style = "padding-right: 15px"), + # uiOutput(NS(id, "chain")), + style = "display: inline-flex" + ), + if(is.null(navTagList)) + fluidRow( + column(12, ui) + ) + else + fluidRow( + column(10, ui), + column(2, navTagList) + ) + ) +} + +#' @import shiny +#' +#' @noRd +pagesUI <- function(id, parent.id, main.env){ + steps <- isolate(main.env$VALUES$steps) + .nb <- length(steps) + + .ui.args <- vector("list", .nb) + sapply( + seq_along(steps), + function(i, main.env) { + page <- steps[i] + + .ui.args[[i]] <<- tabPage( + title = page, + ui = do.call( + what = switch(i, + "SelectDPUI", + "DataFilesUI", + "AttributesUI", + "CatVarsUI", + "GeoCovUI", + "TaxCovUI", + "PersonnelUI", + "MiscUI", + "MakeEMLUI" + ), + args = list( + id = NS(parent.id, page), + main.env = main.env + ) + ), + navTagList = if (i > 1) + tagList( + quitButton(id), + saveButton(id), + if (i != 2) prevTabButton(id, i), + if (i != .nb) nextTabButton(id, i), + tags$hr(), + actionButton(NS(id, "help"), "Help", icon("question-circle")) + ) + else + NULL + ) + }, + main.env = main.env) + + .ui.args$id = NS(id, "wizard") + .ui.args$type = "hidden" + + do.call("tabsetPanel", .ui.args) +} + +# Server ==== + +#' @noRd +#' +#' utility function for pages +changePage <- function(from, to) { + observeEvent(input[[paste(from, to, sep = "_")]], { + EAL$page <- EAL$page + to - from + if(to > from) + EAL$.next <- .EAL$.next+1 + if(from > to) + EAL$.prev <- .EAL$.prev+1 + }) +} + +#' Wizard pages server +#' +#' @noRd +pagesServer <- function(id, steps) { + moduleServer(id, function(input, output, session) { + steps <- main.env$VALUES$steps + EAL <- main.env$EAL + + ids <- seq_along(steps) + lapply(ids[-1], function(i) onQuit(i)) # modules + lapply(ids[-1], function(i) onSave(i)) # modules + lapply(ids[-1], function(i) changePage(i, i-1)) # observers + lapply(ids[-length(steps)], function(i) changePage(i, i+1)) # observers + + # * Chain ==== + # output$chain <- renderUI({ + # validate( + # need(.EAL$page > 1, "") + # ) + # + # return( + # tags$span( + # tagList( + # lapply(seq(.EAL$history)[-1], function(ind) { + # .step.name <- .EAL$history[ind] + # + # if (.step.name != "Taxonomic Coverage") { + # .style <- "color: dodgerblue;" + # .description <- paste(.step.name, "(mandatory)") + # } else { + # .style <- "color: lightseagreen;" + # .description <- paste(.step.name, "(facultative)") + # } + # + # return( + # actionLink( + # ns(paste0("chain_", .step.name)), + # "", + # if (.step.name == .EAL$current) { + # icon("map-marker") + # } else { + # icon("circle") + # }, + # style = .style + # ) %>% shinyBS::tipify( + # title = .description + # # , placement = "bottom" + # # , trigger = "hover" + # ) + # ) # end of return + # }), + # paste0( + # "Step ", .EAL$page, + # "/", length(steps), + # ": ", .EAL$current + # ) + # ), + # style = "position: right" + # ) + # ) + # }) + # + # observe({ + # validate( + # need( + # exists("main.env") && isTruthy(names(input)), + # "Not initialized" + # ), + # need( + # isTruthy(.EAL$history), + # "No history available" + # ), + # need( + # any(sapply( + # .EAL$history, + # grepl, + # x = names(input) + # ) %>% unlist()) && + # length(.EAL$history) > 1, + # "No history available" + # ) + # ) + # + # sapply(seq(.EAL$history)[-1], function(.ind) { + # id <- paste0("chain_", .EAL$history[.ind]) + # + # observeEvent(input[[id]], { + # req(input[[id]] && .ind != .EAL$page) + # .EAL$page <- .ind + # saveReactive() # Set this up correctly + # + # # trigger changes + # if(.ind > .EAL$page) + # EAL$.next <- EAL$.next + 1 + # if(.ind < EAL$page) + # EAL$.prev <- EAL$.prev + 1 + # }) + # }) + }) +} + +# * Quit ==== + +#' @noRd +#' +#' @import shiny +quitButton <- function(id) { + actionButton( + NS(id, "quit"), + "Quit", + icon = icon("sign-out-alt"), + width = "100%" + ) +} + +#' @noRd +#' +#' @import shiny +#' @importFrom shinyjs onclick disable enable +onQuit <- function(id, main.env) { + moduleServer(id, function(input, output, session) { + save.variable <- main.env$save.variable + + # modal dialog for quitting data description + quitModal <- modalDialog( + title = "You are leaving data description.", + "Are you sure to leave? Some of your metadata have maybe not been saved.", + easyClose = FALSE, + footer = tagList( + actionButton(NS(id, "cancel"), "Cancel"), + actionButton(NS(id, "save_quit"), "Save & Quit"), + actionButton( + NS(id, "simple_quit"), + "Quit", + icon("times-circle"), + class = "redButton" + ) + ) + ) + + # quits simply + observeEvent(input$cancel, + { + req(input$quit) + req(input$cancel) + removeModal() + }, + label = "Cancel quit" + ) + + # show modal on 'quit' button clicked + observeEvent(input$quit, + { + req(input$quit) + showModal(quitModal) + }, + label = "EAL quit?" + ) + + # calls saveRDS method and quits + observeEvent(input$save_quit_button, + { + req(input$quit) + req(input$save_quit_button) + + # Save work at this state + saveReactive(save.variable) + }, + priority = 1, + label = "EAL save+quit" + ) + + # quits simply + observeEvent({ + input$simple_quit + input$save_quit_button + }, { + req(input$quit) + removeModal() + + # Clean & reset variables + main.env$EAL$history <- "SelectDP" + main.env$EAL$page <- 1 + }, + priority = 0, + label = "EAL quit", + ignoreInit = TRUE + ) + }) +} + +# * Save ==== + +#' @noRd +#' +#' @import shiny +saveButton <- function(id) { + actionButton( + NS(id, "save"), + "Save", + icon = icon("save", class = "regular"), + width = "100%" + ) +} + +#' @noRd +#' +#' @import shiny +#' @importFrom shinyjs onclick disable enable +onSave <- function(id, main.env){ + moduleServer(id, function(input, output, session) { + observeEvent(input$save, + { + req(input$save) + NSB$SAVE <- NSB$SAVE + 1 + }, + label = "NSB save" + ) + }) +} + +# * Previous ==== + +#' @noRd +#' +#' @import shiny +prevTabButton <- function(id, i) { + actionButton( + NS(id, paste(i, i-1, sep = "_")), + "Previous", + icon = icon("arrow-left"), + width = "100%" + ) +} + +# * Next ==== + +#' @noRd +#' +#' @import shiny +nextTabButton <- function(id, i) { + actionButton( + NS(id, paste(i, i+1, sep = "_")), + "Next", + icon = icon("arrow-right"), + width = "100%" + ) +} diff --git a/R/headerScript.R b/R/headerScript.R index e1e9d14..1ffec95 100644 --- a/R/headerScript.R +++ b/R/headerScript.R @@ -79,7 +79,10 @@ reactiveValues( thresholds = reactiveValues( files.size.max = 500000 - ) + ), + steps = c("SelectDP", "Data Files", "Attributes", "Categorical Variables", + "Geographic Coverage", "Taxonomic Coverage", "Personnel", "Miscellaneous", + "Make EML") ), envir = main.env ) @@ -152,23 +155,30 @@ envir = main.env ) - # EAL ==== - + # EAL rv ==== assign( "EAL", reactiveValues( - history = "SelectDP", - navigate = 1, - current = c(name = "SelectDP", completed = FALSE), - iterator = 0 + page = 1, # page number + history = character(), # all browsed pages names in steps + current = character(), # last of history + completed = FALSE, # is current page completed? + tag.list = tagList(), # side HTML tags to display + .next = 0, + .prev = 0 ), envir = main.env ) - # Patterns ==== + assign( + "save.variable", + initReactive(main.env = main.env), + envir = main.env + ) + # Patterns ==== assign( - "PATTERNS", + "PATTERNS", reactiveValues( # match one expression for latitude or longitude coordinates = "[+-]?[[:digit:]]+[.,]*[[:digit:]]*", diff --git a/R/orcid_connect.R b/R/orcid_connect.R index 001a396..f97184a 100644 --- a/R/orcid_connect.R +++ b/R/orcid_connect.R @@ -2,7 +2,7 @@ orcidUI <- function(id, globals) { ns <- NS(id) - uiOutput(ns("infos")) + uiOutput(NS(id, "infos")) } #' @import shiny @@ -18,9 +18,9 @@ orcid <- function(input, output, session, main.env) { output$infos <- renderUI({ if (isFALSE(.SETTINGS$logged)) { tagList( - textInput(ns("orcid"), "Write your ORCID here"), + textInput(NS(id, "orcid"), "Write your ORCID here"), actionButton( - ns("connect"), + NS(id, "connect"), "Connect with ORCID", icon = icon("sign-in-alt") ) @@ -35,7 +35,7 @@ orcid <- function(input, output, session, main.env) { ), column(6) ), - actionButton(ns("disconnect"), "Logout", icon = icon("sign-out-alt")) + actionButton(NS(id, "disconnect"), "Logout", icon = icon("sign-out-alt")) ) } }) diff --git a/R/fill-module_functions.R b/R/savevariable_functions.R similarity index 83% rename from R/fill-module_functions.R rename to R/savevariable_functions.R index b8f6bc1..d771a88 100644 --- a/R/fill-module_functions.R +++ b/R/savevariable_functions.R @@ -1,4 +1,3 @@ -# Manage save.variable variable ----------------------------------------------------- #' @import shiny #' #' @noRd @@ -18,9 +17,9 @@ initReactive <- function(sub.list = NULL, save.variable = NULL, main.env) { # emlal reactivelist management if (is.null(sub.list) || sub.list == "emlal") { save.variable$emlal <- reactiveValues( - step = main.env$EAL$navigate, + step = isolate(main.env$EAL$page), quick = FALSE, - history = main.env$EAL$history, + history = isolate(main.env$EAL$history), SelectDP = reactiveValues( dp.name = NULL, dp.path = NULL, @@ -77,19 +76,14 @@ initReactive <- function(sub.list = NULL, save.variable = NULL, main.env) { }) } -#' @describeIn initReactive -#' -#' @description save the `save.variable` variable at wanted location -#' -#' @return -#' `save.variable` modified. -#' #' @import shiny #' @importFrom jsonlite write_json serializeJSON +#' +#' @noRd saveReactive <- function( save.variable, rv = NULL, - main.env = NULL + write = FALSE ) { withProgress({ setProgress(1 / 3, "Module save") @@ -113,7 +107,8 @@ saveReactive <- function( ), args = list( save.variable = savevar, - rv = rv[[1]] + rv = rv[[1]], + write = write ) ) @@ -189,22 +184,34 @@ saveReactive <- function( return(save.variable) } -#' @title readFilesText -#' -#' @param files files basename located in the same directory or, -#' if prefix = NULL, list of full filenames to read -#' @param prefix common file prefix for all file names -#' specified in 'files'. By default, sep = "/" -#' -#' @importFrom readtext readtext -readPlainText <- function(files, prefix = NULL, sep = "/", ...) { - if (is.null(prefix)) sep <- "" - - readtext::readtext( - paste( - prefix, - files, - sep = sep - ) - )$text +#' @import shiny +setSavevar <- function(content, save.variable, lv = 1, root = "root") { + + lapply( + names(content), + function(label) { + sub.content <- content[[label]] + type.content <- typeof(sub.content) + sub.save.variable <- savevar[[label]] + type.save.variable <- typeof(sub.savevar) + + if (is.reactivevalues(sub.save.variable)) { + if (!is.data.frame(sub.content) && + is.list(sub.content)) { + x <- setSavevar(content[[label]], save.variable[[label]], lv = lv + 1, root = label) + } + else { + x <- sub.content + } + } + else { + x <- sub.content + } + + isolate(save.variable[[label]] <- x) + return(NULL) + } + ) + + return(save.variable) } \ No newline at end of file diff --git a/R/server.R b/R/server.R index 88c9770..1e038ca 100644 --- a/R/server.R +++ b/R/server.R @@ -8,44 +8,31 @@ # get app arguments app.args <- golem::get_golem_options() - dev <- app.args$dev main.env <- app.args$main.env # initialize global variables save.variable <- NULL - # DEV ----------------------------------------------------- - if (dev) { + if (main.env$dev) { shinyjs::onclick("dev", { - req(input$side_menu != "fill") browser() }, asis = TRUE ) } - # Head bar server ----------------------------------------------------- + # Head bar server ---- # Options observeEvent(input$settings, { updateTabItems(session, "side_menu", "settings") }) - callModule(settings, "settings", main.env) + settings("settings", main.env) - ## modules called ----------------------------------------------------- - observeEvent(input$side_menu, { - save.variable <- switch(input$side_menu, - # fill - fill = callModule(fill, "fill", main.env), - # upload - upload = callModule(upload, "upload", main.env), - # doc - documentation = callModule(documentation, "documentation"), - # about - about = callModule(about, "about"), - # default - NULL - ) - }) + ## modules called ---- + fill("fill", main.env) + upload("upload", main.env) + documentation("documentation") + about("about") } diff --git a/R/settings.R b/R/settings.R index 9a97d6a..3dfda07 100644 --- a/R/settings.R +++ b/R/settings.R @@ -18,7 +18,7 @@ settingsUI <- function(id, wip) { created on this instance of MetaShARK. By logging in, you will be able to write private data packages that will not appear on other users list. "), - orcidUI(ns("orcid")), + orcidUI(NS(id, "orcid")), # TODO POC ORCID class = "inputBox wip" ) @@ -28,14 +28,14 @@ settingsUI <- function(id, wip) { column( 8, tags$h2("Metacat settings"), - textAreaInput(ns("metacat_token"), + textAreaInput(NS(id, "metacat_token"), "Authentication token", width = "120%" ), - checkboxInput(ns("test_metacat"), "Test MetaCat", value = TRUE), - actionButton(ns("metacat_save"), "Save"), + checkboxInput(NS(id, "test_metacat"), "Test MetaCat", value = TRUE), + actionButton(NS(id, "metacat_save"), "Save"), if (isTRUE(wip)) { - textOutput(ns("verbose_token")) + textOutput(NS(id, "verbose_token")) } ), column( @@ -59,11 +59,11 @@ settingsUI <- function(id, wip) { column( 8, textAreaInput( - ns("cedar_token"), + NS(id, "cedar_token"), "Authentication token", width = "120%" ), - actionButton(ns("cedar_save"), "Save") + actionButton(NS(id, "cedar_save"), "Save") ), column( 4, @@ -87,28 +87,30 @@ settingsUI <- function(id, wip) { #' @import shiny #' @importFrom shinyjs onclick #' @importFrom cedarr accessOntology -settings <- function(input, output, session, main.env) { - # Sessionning ==== - callModule(orcid, "orcid", main.env) - - # Metacat token ==== - observeEvent(input$test_metacat, { - req(input$test_metacat) - main.env$SETTINGS$metacat.test <- input$test_metacat - }) - - observeEvent(input$metacat_save, { - main.env$SETTINGS$metacat.token <- input$metacat_token - showNotification(id = "metacat_set", "Dataone token set.", type = "message") - }) - - # CEDAR token ==== - observeEvent({ - input$cedar_token - input$cedar_save - }, { - req(input$cedar_token) - .SETTINGS$cedar.token <- input$cedar_token - main.env$SEMANTICS$ontologies <- cedarr::accessOntology(.SETTINGS$cedar.token) +settings <- function(id, main.env){ + moduleServer(id, function(input, output, session) { + # Sessionning ==== + orcid("orcid", main.env) + + # Metacat token ==== + observeEvent(input$test_metacat, { + req(input$test_metacat) + main.env$SETTINGS$metacat.test <- input$test_metacat + }) + + observeEvent(input$metacat_save, { + main.env$SETTINGS$metacat.token <- input$metacat_token + showNotification(id = "metacat_set", "Dataone token set.", type = "message") + }) + + # CEDAR token ==== + observeEvent({ + input$cedar_token + input$cedar_save + }, { + req(input$cedar_token) + .SETTINGS$cedar.token <- input$cedar_token + main.env$SEMANTICS$ontologies <- cedarr::accessOntology(.SETTINGS$cedar.token) + }) }) -} +} \ No newline at end of file diff --git a/R/ui.R b/R/ui.R index 8c4ae7d..39a22bb 100644 --- a/R/ui.R +++ b/R/ui.R @@ -36,7 +36,7 @@ ), titleWidth = .menu.width ), - ## Menus ----------------------------------------------------- + ## Menus ---- dashboardSidebar( sidebarMenu( id = "side_menu", @@ -74,7 +74,7 @@ ), width = .menu.width ), # end sidebar - ## Content ----------------------------------------------------- + ## Content ---- dashboardBody( tags$script(HTML("$('body').addClass('fixed');")), tabItems( @@ -84,7 +84,7 @@ ), tabItem( tabName = "fill", - fillUI("fill", dev) + fillUI("fill", main.env) ), tabItem( tabName = "upload", @@ -103,7 +103,7 @@ settingsUI("settings", wip) ) ) - ) # end body + ) ) # end dashboard - ) %>% shinycssloaders::withSpinner # end taglist + ) # end taglist } diff --git a/R/upload-module.R b/R/upload-module.R index 3c1203b..493f956 100644 --- a/R/upload-module.R +++ b/R/upload-module.R @@ -31,40 +31,40 @@ uploadUI <- function(id, main.env) { tagList( tabsetPanel( id = "upload", - # Upload ----------------------------------------------------- + # Upload ---- tabPanel( title = "upload", - if (dev) actionButton(ns("dev"), "Dev"), - # select endpoint ----------------------------------------------------- + if (dev) actionButton(NS(id, "dev"), "Dev"), + # select endpoint ---- tags$h3("Select your MetaCat portal"), tags$div( tags$p(tags$code("dev"), "portals are under construction. No guarantee is given of their consistance.", tags$code("prod"), "portals are completely functional. Chosing 'Other' will ask you to input some technical information."), selectInput( - ns("endpoint"), + NS(id, "endpoint"), "Available metacats:", c(registeredEndpoints$mn, "Other") ), - uiOutput(ns("actual-endpoint")), + uiOutput(NS(id, "actual-endpoint")), tagList( tags$p("Want your endpoint to be listed? get in touch with the dev team !") ), class = "leftMargin inputBox" ), tags$hr(), - # check authentication token ----------------------------------------------------- + # check authentication token ---- tags$h3("Get your authentication token"), tags$div( tags$p("The ", tags$b("authentication token"), " is a user-specific characters key. It allows the user to authenticate a connection between its current location and a distant server, actually the metadata catalog. To upload a data package, the authentication token is required."), - actionButton(ns("toSettings"), "Go to settings", icon("gear")), + actionButton(NS(id, "toSettings"), "Go to settings", icon("gear")), class = "leftMargin inputBox" ), - # files input ----------------------------------------------------- + # files input ---- tags$h3("Select your data package files"), tags$div( # data package input @@ -76,7 +76,7 @@ uploadUI <- function(id, main.env) { # * DP ==== tags$h4("Select a data package"), selectInput( - ns("DP"), + NS(id, "DP"), "Data package", choices = c( None = "", @@ -88,46 +88,46 @@ uploadUI <- function(id, main.env) { tags$h4("Add or remove files"), # * Metadata ==== fileInput( - ns("metadata"), + NS(id, "metadata"), "EML-valid file (only one allowed)" ), - textOutput(ns("warnings-metadata")), + textOutput(NS(id, "warnings-metadata")), # * Data ==== fileInput( - ns("data"), + NS(id, "data"), "Data files described in your EML file" ), - textOutput(ns("warnings-data")), + textOutput(NS(id, "warnings-data")), # * Scripts ==== fileInput( - ns("scripts"), + NS(id, "scripts"), "Scripts used to produce or process data" ), - textOutput(ns("warnings-scripts")) + textOutput(NS(id, "warnings-scripts")) ), column(3, tags$h4("Files list"), - uiOutput(ns("filesList")) + uiOutput(NS(id, "filesList")) ) ), class = "leftMargin inputBox" ), - # Constraints ----------------------------------------------------- + # Constraints ---- # div(id="constraints_div", # tags$h4("Add constraints between script and data files"), - # actionButton(ns("add_constraint"), "", icon = icon("plus"), width = "40px") + # actionButton(NS(id, "add_constraint"), "", icon = icon("plus"), width = "40px") # ), # tags$hr(), actionButton( - ns("process"), + NS(id, "process"), "Process", icon = icon("rocket"), width = "100%" ) ), # end of upload tab - # Update ----------------------------------------------------- + # Update ---- tabPanel( title = "update", tags$div( @@ -153,229 +153,230 @@ uploadUI <- function(id, main.env) { #' @importFrom shinyjs enable disable click #' @importFrom data.table fread fwrite #' @importFrom mime guess_type -upload <- function(input, output, session, main.env) { - ns <- session$ns - - registeredEndpoints <- data.table::fread(main.env$PATHS$resources$registeredEndpoints.txt) - dev <- main.env$dev - - # Select endpoint ---- - endpoint <- reactive({ - input$endpoint - }) - - memberNode <- reactive({ - if (endpoint() != "Other") { - registeredEndpoints %>% - dplyr::filter(mn == endpoint()) %>% - dplyr::select(URL) - } else { - callModule(URL_Input, "actual-endpoint") - } - }) - - output$`actual-endpoint` <- renderUI({ - if (endpoint() != "Other") { - tags$p(tags$b("Current endpoint:"), memberNode()) - } else { - URL_Input_UI(ns("actual-endpoint"), "Write the URL of the Member Node") - } - }) - - # Token input ----------------------------------------------------- - observeEvent(input$toSettings, { - shinyjs::click("appOptions", asis = TRUE) - }, ignoreInit = TRUE) - - observe({ - if (!is.character(options("dataone_token")) || - !is.character(options("dataone_test_token")) || - (is.null(options("dataone_token")) && is.null(options("dataone_test_token"))) - ) { - output$token_status <- renderUI({ - tags$div("UNFILLED", class = "danger") - }) - shinyjs::disable("process") - } - else { - output$token_status <- renderUI({ - tags$div("FILLED", class = "valid") - }) - shinyjs::enable("process") - } - }) - - # Files input ----------------------------------------------------- - rv <- reactiveValues( - md = data.frame(stringsAsFactors = FALSE), - data = data.frame(stringsAsFactors = FALSE), - scr = data.frame(stringsAsFactors = FALSE) - ) - - observeEvent(input$DP, { - .dir <- gsub("/+", "/", input$DP) - .id <- basename(.dir) %>% sub("_emldp$", "", .) - .eml.files <- sprintf("%s/%s/eml", .dir, .id) %>% - dir(full.names = TRUE) - rv$md <- data.frame( - name = basename(.eml.files), - size = base::file.size(.eml.files), - type = mime::guess_type(.eml.files), - datapath= .eml.files - ) +upload <- function(id, main.env){ + moduleServer(id, function(input, output, session) { - .data.files <- sprintf("%s/%s/data_objects", .dir, .id) %>% - dir(full.names = TRUE) - rv$data <- data.frame( - name = basename(.data.files), - size = base::file.size(.data.files), - type = mime::guess_type(.data.files), - datapath = .data.files - ) - }, - ignoreInit = TRUE, - label = "DPinput" - ) - - observeEvent(input$metadata,{ - rv$md <- input$metadata - showNotification( - "Only one metadata file allowed", - type = "message" + registeredEndpoints <- data.table::fread(main.env$PATHS$resources$registeredEndpoints.txt) + dev <- main.env$dev + + # Select endpoint ---- + endpoint <- reactive({ + input$endpoint + }) + + memberNode <- reactive({ + if (endpoint() != "Other") { + registeredEndpoints %>% + dplyr::filter(mn == endpoint()) %>% + dplyr::select(URL) + } else { + URL_Input("actual-endpoint") + } + }) + + output$`actual-endpoint` <- renderUI({ + if (endpoint() != "Other") { + tags$p(tags$b("Current endpoint:"), memberNode()) + } else { + URL_Input_UI(NS(id, "actual-endpoint"), "Write the URL of the Member Node") + } + }) + + # Token input ---- + observeEvent(input$toSettings, { + shinyjs::click("appOptions", asis = TRUE) + }, ignoreInit = TRUE) + + observe({ + if (!is.character(options("dataone_token")) || + !is.character(options("dataone_test_token")) || + (is.null(options("dataone_token")) && is.null(options("dataone_test_token"))) + ) { + output$token_status <- renderUI({ + tags$div("UNFILLED", class = "danger") + }) + shinyjs::disable("process") + } + else { + output$token_status <- renderUI({ + tags$div("FILLED", class = "valid") + }) + shinyjs::enable("process") + } + }) + + # Files input ---- + rv <- reactiveValues( + md = data.frame(stringsAsFactors = FALSE), + data = data.frame(stringsAsFactors = FALSE), + scr = data.frame(stringsAsFactors = FALSE) ) - }) - observeEvent(input$data,{ - .add <- input$data - req(checkTruth(.add)) - browser() # Update list instead of erasing - rv$data <- rbind(rv$data, .add) - }) - observeEvent(input$scripts,{ - .add <- input$scripts - req(checkTruth(.add)) - browser() # Update list instead of erasing - rv$scr <- rbind(input$scripts, .add) - }) - - output$filesList <- renderUI({ - validate( - need( - dim(rv$md) > 0 || - dim(rv$data) > 0 || - dim(rv$scr) > 0, - "No file selected" + + observeEvent(input$DP, { + .dir <- gsub("/+", "/", input$DP) + .id <- basename(.dir) %>% sub("_emldp$", "", .) + .eml.files <- sprintf("%s/%s/eml", .dir, .id) %>% + dir(full.names = TRUE) + rv$md <- data.frame( + name = basename(.eml.files), + size = base::file.size(.eml.files), + type = mime::guess_type(.eml.files), + datapath= .eml.files ) + + .data.files <- sprintf("%s/%s/data_objects", .dir, .id) %>% + dir(full.names = TRUE) + rv$data <- data.frame( + name = basename(.data.files), + size = base::file.size(.data.files), + type = mime::guess_type(.data.files), + datapath = .data.files + ) + }, + ignoreInit = TRUE, + label = "DPinput" ) - tagList( - if(dim(rv$md)[1] > 0) - checkboxGroupInput( - ns("md-files"), - label = "EML file", - choices = rv$md$name - ), - if(dim(rv$data)[1] > 0) - checkboxGroupInput( - ns("data-files"), - label = "Data files", - choices = rv$data$name - ), - if(dim(rv$scr)[1] > 0) - checkboxGroupInput( - ns("scr-files"), - label = "Scripts", - choices = rv$scr$name - ), - actionButton(ns("rmv"), "Remove", class = "danger") - ) - }) - - observeEvent(input$rmv, { - .rmv <- input$`md-files` - if(checkTruth(.rmv)){ - .ind <- match(.rmv, rv$md$name) - rv$md <- rv$md[-.ind,] - } - .rmv <- input$`data-files` - if(checkTruth(.rmv)){ - .ind <- match(.rmv, rv$data$name) - rv$data <- rv$data[-.ind,] - } - .rmv <- input$`scr-files` - if(checkTruth(.rmv)){ - .ind <- match(.rmv, rv$scr$name) - rv$scr <- rv$scr[-.ind,] - } - }, ignoreInit = TRUE) - - observe({ - if ( - dim(rv$md)[1] != 1 || - dim(rv$data)[1] < 1 - ) { - shinyjs::disable("process") - } else { - shinyjs::enable("process") - } + observeEvent(input$metadata,{ + rv$md <- input$metadata + showNotification( + "Only one metadata file allowed", + type = "message" + ) + }) + observeEvent(input$data,{ + .add <- input$data + req(checkTruth(.add)) + browser() # Update list instead of erasing + rv$data <- rbind(rv$data, .add) + }) + observeEvent(input$scripts,{ + .add <- input$scripts + req(checkTruth(.add)) + browser() # Update list instead of erasing + rv$scr <- rbind(input$scripts, .add) + }) - if ( - dim(rv$scr)[1] == 0 || - dim(rv$data)[1] == 0 - ) { - shinyjs::disable("add_constraint") - } else { - shinyjs::enable("add_constraint") - } - }) - - # Process ----------------------------------------------------- - observeEvent(input$process, { - disable("process") + output$filesList <- renderUI({ + validate( + need( + dim(rv$md) > 0 || + dim(rv$data) > 0 || + dim(rv$scr) > 0, + "No file selected" + ) + ) + + tagList( + if(dim(rv$md)[1] > 0) + checkboxGroupInput( + NS(id, "md-files"), + label = "EML file", + choices = rv$md$name + ), + if(dim(rv$data)[1] > 0) + checkboxGroupInput( + NS(id, "data-files"), + label = "Data files", + choices = rv$data$name + ), + if(dim(rv$scr)[1] > 0) + checkboxGroupInput( + NS(id, "scr-files"), + label = "Scripts", + choices = rv$scr$name + ), + actionButton(NS(id, "rmv"), "Remove", class = "danger") + ) + }) - md.format <- EML::read_eml(as.character(rv$md$datapath))$schemaLocation %>% - strsplit(split = " ") %>% - unlist %>% - utils::head(n = 1) + observeEvent(input$rmv, { + .rmv <- input$`md-files` + if(checkTruth(.rmv)){ + .ind <- match(.rmv, rv$md$name) + rv$md <- rv$md[-.ind,] + } + .rmv <- input$`data-files` + if(checkTruth(.rmv)){ + .ind <- match(.rmv, rv$data$name) + rv$data <- rv$data[-.ind,] + } + .rmv <- input$`scr-files` + if(checkTruth(.rmv)){ + .ind <- match(.rmv, rv$scr$name) + rv$scr <- rv$scr[-.ind,] + } + }, ignoreInit = TRUE) - out <- uploadDP( - mn = registeredEndpoints %>% - dplyr::filter(mn == endpoint()) %>% - dplyr::select(URL) %>% - as.character, - cn = registeredEndpoints %>% - dplyr::filter(mn == endpoint()) %>% - dplyr::select(cn) %>% - as.character, - token = list( - test = main.env$SETTINGS$metacat.test, - prod = main.env$SETTINGS$metacat.token - ), - eml = list( - file = rv$md$datapath, - format = md.format - ), - data = list( - file = rv$data$datapath, - format = mime::guess_type(rv$data$datapath) - ), - scripts = if (dim(rv$scr)[1] > 0) { - list( - file = rv$scr$datapath, - format = mime::guess_type(rv$scr$datapath) - ) + observe({ + if ( + dim(rv$md)[1] != 1 || + dim(rv$data)[1] < 1 + ) { + shinyjs::disable("process") } else { - c() - }, - formats = main.env$FORMAT$dataone.list$MediaType, - use.doi = FALSE - ) - - if (class(out) == "try-error") { - showNotification(out[1], type = "error") - } else { - showNotification(paste("Uploaded DP", out), type = "message") - } + shinyjs::enable("process") + } + + if ( + dim(rv$scr)[1] == 0 || + dim(rv$data)[1] == 0 + ) { + shinyjs::disable("add_constraint") + } else { + shinyjs::enable("add_constraint") + } + }) - shinyjs::enable("process") + # Process ---- + observeEvent(input$process, { + disable("process") + + md.format <- EML::read_eml(as.character(rv$md$datapath))$schemaLocation %>% + strsplit(split = " ") %>% + unlist %>% + utils::head(n = 1) + + out <- uploadDP( + mn = registeredEndpoints %>% + dplyr::filter(mn == endpoint()) %>% + dplyr::select(URL) %>% + as.character, + cn = registeredEndpoints %>% + dplyr::filter(mn == endpoint()) %>% + dplyr::select(cn) %>% + as.character, + token = list( + test = main.env$SETTINGS$metacat.test, + prod = main.env$SETTINGS$metacat.token + ), + eml = list( + file = rv$md$datapath, + format = md.format + ), + data = list( + file = rv$data$datapath, + format = mime::guess_type(rv$data$datapath) + ), + scripts = if (dim(rv$scr)[1] > 0) { + list( + file = rv$scr$datapath, + format = mime::guess_type(rv$scr$datapath) + ) + } else { + c() + }, + formats = main.env$FORMAT$dataone.list$MediaType, + use.doi = FALSE + ) + + if (class(out) == "try-error") { + showNotification(out[1], type = "error") + } else { + showNotification(paste("Uploaded DP", out), type = "message") + } + + shinyjs::enable("process") + }) }) } diff --git a/R/upload-module_functions.R b/R/upload-module_functions.R index 34db758..fa61ab9 100644 --- a/R/upload-module_functions.R +++ b/R/upload-module_functions.R @@ -28,7 +28,7 @@ uploadDP <- function( formats, use.doi = FALSE ) { - # Set variables ----------------------------------------------------- + # Set variables ---- message("Init") @@ -38,7 +38,7 @@ uploadDP <- function( doi <- dataone::generateIdentifier(mn, "DOI") } # TODO check this feature - # # Write DP ----------------------------------------------------- + # # Write DP ---- # set data package dp <- methods::new("DataPackage") @@ -90,13 +90,13 @@ uploadDP <- function( ) } - # # Access rules ----------------------------------------------------- + # # Access rules ---- message("Access") accessRules <- NA # TODO allow customized access rules - # # Upload ----------------------------------------------------- + # # Upload ---- d1c <- dataone::D1Client(cn, mn) @@ -130,15 +130,15 @@ describeWorkflowUI <- function(id, sources, targets) { ns <- NS(id) span( - id = ns("span"), - div(selectInput(ns("script"), "Source script", sources), + id = NS(id, "span"), + div(selectInput(NS(id, "script"), "Source script", sources), style = "display: inline-block; vertical-align: middle;" ), "describes", - div(selectInput(ns("data"), "Target data file", targets), + div(selectInput(NS(id, "data"), "Target data file", targets), style = "display: inline-block; vertical-align: middle;" ), - actionButton(ns("remove"), "", icon("minus"), class = "redButton"), + actionButton(NS(id, "remove"), "", icon("minus"), class = "redButton"), style = "display: inline-block;" ) } @@ -157,7 +157,7 @@ describeWorkflow <- function(input, output, session) { # Remove observeEvent(input$remove, { removeUI( - selector = paste0("#", ns("span")) + selector = paste0("#", NS(id, "span")) ) rv <- NULL }) diff --git a/R/utils-URL_Input.R b/R/utils-URL_Input.R index be44b8b..f92be5f 100644 --- a/R/utils-URL_Input.R +++ b/R/utils-URL_Input.R @@ -13,10 +13,10 @@ #' @import shiny URL_Input_UI <- function(id, label = "URL", width = "100%") { ns <- NS(id) - + tagList( - textInput(ns("url"), label, placeholder = "https://github.com/earnaud/MetaShARK-v2"), - textOutput(ns("warnings")) + textInput(NS(id, "url"), label, placeholder = "https://github.com/earnaud/MetaShARK-v2"), + textOutput(NS(id, "warnings")) ) } @@ -26,25 +26,27 @@ URL_Input_UI <- function(id, label = "URL", width = "100%") { #' #' @import shiny #' @importFrom RCurl url.exists -URL_Input <- function(input, output, session) { - # variable initialization - url <- reactiveVal(character()) - - # actions - observeEvent(input$url, { - is.url <- RCurl::url.exists(input$url) - - output$warnings <- renderText({ - validate( - need(is.url, "Invalid URL target.") - ) - return(NULL) +URL_Input <- function(id){ + moduleServer(id, function(input, output, session) { + # variable initialization + url <- reactiveVal(character()) + + # actions + observeEvent(input$url, { + is.url <- RCurl::url.exists(input$url) + + output$warnings <- renderText({ + validate( + need(is.url, "Invalid URL target.") + ) + return(NULL) + }) + + url <- NA_character_ + req(is.url) + url <- input$url }) - - url <- NA_character_ - req(is.url) - url <- input$url + + return(url) }) - - return(url) } diff --git a/R/utils-collapsible.R b/R/utils-collapsible.R index 2dc91e6..ca97a69 100644 --- a/R/utils-collapsible.R +++ b/R/utils-collapsible.R @@ -12,13 +12,13 @@ #' @importFrom shinyjs useShinyjs hidden collapsibleUI <- function(id, label, .hidden = TRUE, ..., class = NULL) { ns <- NS(id) - - content <- tags$div(id = ns("area"), tagList(...), class = class) - + + content <- tags$div(id = NS(id, "area"), tagList(...), class = class) + tagList( shinyjs::useShinyjs(), actionLink( - ns("link"), + NS(id, "link"), label, icon = if (isTRUE(.hidden)) icon("chevron-right") else icon("chevron-down") ), @@ -36,21 +36,23 @@ collapsibleUI <- function(id, label, .hidden = TRUE, ..., class = NULL) { #' @importFrom shinyjs toggle #' #' @noRd -collapsible <- function(input, output, session) { - observeEvent(input$link, { - shinyjs::toggle( - id = "area", - anim = TRUE, - animType = "slide", - time = 0.25 - ) - - if (input$link %% 2 == 1) { - .tmp <- "chevron-down" - } else { - .tmp <- "chevron-right" - } - - updateActionButton(session, "link", icon = icon(.tmp)) +collapsible <- function(id){ + moduleServer(id, function(input, output, session) { + observeEvent(input$link, { + shinyjs::toggle( + id = "area", + anim = TRUE, + animType = "slide", + time = 0.25 + ) + + if (input$link %% 2 == 1) { + .tmp <- "chevron-down" + } else { + .tmp <- "chevron-right" + } + + updateActionButton(session, "link", icon = icon(.tmp)) + }) }) -} +} \ No newline at end of file diff --git a/R/utils-listReactiveValues.R b/R/utils-listReactiveValues.R index d450c15..e084d62 100644 --- a/R/utils-listReactiveValues.R +++ b/R/utils-listReactiveValues.R @@ -1,7 +1,7 @@ #' @title listReactiveValues #' -#' @description Allows to turn a `reactiveValues`` object -#' into a list. Uses recursive method. +#' @description Allows to turn a `reactiveValues`` object into a list. Uses +#' recursive method. #' #' @param rv reactiveValues to turn into list #' @param lv (verbose purposes) diff --git a/R/utils-markdownInput.R b/R/utils-markdownInput.R index 220ef16..3290e9e 100644 --- a/R/utils-markdownInput.R +++ b/R/utils-markdownInput.R @@ -3,7 +3,7 @@ #' @description A shiny input module designed to allow the user to write markdown and render it as #' a HTML fix. #' -#' @param inputId character. The input slot that will be used to access the value. +#' @param id character. The input slot that will be used to access the value. #' @param label character. Display label for the control, or NULL for no label. #' @param icon character. An optional `icon()` to appear on the button. #' @param preview logical. Shall a preview panel appear? (right-sided, 50\% width) @@ -27,15 +27,14 @@ #' } #' #' shinyApp(ui, server) -markdownInputUI <- function(inputId, label = "Text", icon = TRUE, preview = FALSE, value = "") { - ns <- NS(inputId) +markdownInputUI <- function(id, label = "Text", icon = TRUE, preview = FALSE, value = "") { div( fluidRow( column( if (preview) 6 else 12, if (isFALSE(icon)) tags$b(label) else span(tags$b(label), "(", icon("markdown"), "supported)"), aceEditor( - ns("md"), + NS(id, "md"), value = value, mode = "markdown", showLineNumbers = FALSE, @@ -46,7 +45,7 @@ markdownInputUI <- function(inputId, label = "Text", icon = TRUE, preview = FALS column( 6, h3("Preview:"), - uiOutput(ns("preview")) + uiOutput(NS(id, "preview")) ) } ), @@ -59,16 +58,18 @@ markdownInputUI <- function(inputId, label = "Text", icon = TRUE, preview = FALS #' #' @import shiny #' @importFrom markdown markdownToHTML -markdownInput <- function(input, output, session, preview = FALSE) { - rv <- reactive({ - input$md - }) - - if (preview) { - output$preview <- renderUI({ - HTML(markdownToHTML(file = NULL, text = rv())) +markdownInput <- function(id, preview = FALSE){ + moduleServer(id, function(input, output, session) { + rv <- reactive({ + input$md }) - } - - return(rv) + + if (preview) { + output$preview <- renderUI({ + HTML(markdownToHTML(file = NULL, text = rv())) + }) + } + + return(rv) + }) } diff --git a/R/utils-observersSet.R b/R/utils-observersSet.R deleted file mode 100644 index 039f227..0000000 --- a/R/utils-observersSet.R +++ /dev/null @@ -1,14 +0,0 @@ -observersSet <- function(){ - # Variable - obs <- list() - - # Methods - list( - suspendAll = function(obsSet){ - - }, - runAll = function(obsSet){ - - } - ) -} \ No newline at end of file diff --git a/R/utils-readPlaintext.R b/R/utils-readPlaintext.R new file mode 100644 index 0000000..090018d --- /dev/null +++ b/R/utils-readPlaintext.R @@ -0,0 +1,19 @@ +#' @title readFilesText +#' +#' @param files files basename located in the same directory or, +#' if prefix = NULL, list of full filenames to read +#' @param prefix common file prefix for all file names +#' specified in 'files'. By default, sep = "/" +#' +#' @importFrom readtext readtext +readPlainText <- function(files, prefix = NULL, sep = "/", ...) { + if (is.null(prefix)) sep <- "" + + readtext::readtext( + paste( + prefix, + files, + sep = sep + ) + )$text +} \ No newline at end of file diff --git a/R/utils-setSavevar.R b/R/utils-setSavevar.R deleted file mode 100644 index 6f4c648..0000000 --- a/R/utils-setSavevar.R +++ /dev/null @@ -1,31 +0,0 @@ -#' @import shiny -setSavevar <- function(content, save.variable, lv = 1, root = "root") { - - lapply( - names(content), - function(label) { - sub.content <- content[[label]] - type.content <- typeof(sub.content) - sub.save.variable <- savevar[[label]] - type.save.variable <- typeof(sub.savevar) - - if (is.reactivevalues(sub.save.variable)) { - if (!is.data.frame(sub.content) && - is.list(sub.content)) { - x <- setSavevar(content[[label]], save.variable[[label]], lv = lv + 1, root = label) - } - else { - x <- sub.content - } - } - else { - x <- sub.content - } - - isolate(save.variable[[label]] <- x) - return(NULL) - } - ) - - return(save.variable) -} diff --git a/R/utils-writeText.R b/R/utils-writeText.R index 1a4e87a..090355c 100644 --- a/R/utils-writeText.R +++ b/R/utils-writeText.R @@ -9,7 +9,7 @@ #' #' @export write.text <- function(x, file = ".", collapse = "\n") { - # Validity check ----------------------------------------------------- + # Validity check ---- if (missing(x)) { stop("Error: no text has been provided.") } @@ -24,7 +24,7 @@ write.text <- function(x, file = ".", collapse = "\n") { warning("Length of 'file' > 1 : only the first element has been used.") } - # Process data ----------------------------------------------------- + # Process data ---- if (is.list(x)) { x <- unlist(x) } @@ -32,7 +32,7 @@ write.text <- function(x, file = ".", collapse = "\n") { x <- paste(x, collapse = collapse) } - # Proper write ----------------------------------------------------- + # Proper write ---- fileConn <- file(file) writeLines(x, fileConn) close(fileConn) diff --git a/R/golem_utils_ui.R b/R/utils_withRedStar.R similarity index 100% rename from R/golem_utils_ui.R rename to R/utils_withRedStar.R diff --git a/inst/media/hex-MetaShARK.hex b/inst/media/hex-MetaShARK.hex new file mode 100644 index 0000000..190afa6 Binary files /dev/null and b/inst/media/hex-MetaShARK.hex differ diff --git a/inst/media/hex-MetaShARK.png b/inst/media/hex-MetaShARK.png new file mode 100644 index 0000000..a323b3a Binary files /dev/null and b/inst/media/hex-MetaShARK.png differ diff --git a/man/AttributesUI.Rd b/man/AttributesUI.Rd deleted file mode 100644 index 5c541b5..0000000 --- a/man/AttributesUI.Rd +++ /dev/null @@ -1,21 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/eal_3_Attributes.R -\name{AttributesUI} -\alias{AttributesUI} -\alias{Attributes} -\title{Data Package Template filling} -\usage{ -AttributesUI(id, title, dev) - -Attributes(input, output, session, save.variable, main.env, NSB) -} -\description{ -UI part of the Attributes module. Fill in the attributes of the data package - -server part of the Attributes module. -} -\section{Functions}{ -\itemize{ -\item \code{Attributes}: -}} - diff --git a/man/CatVars.Rd b/man/CatVars.Rd deleted file mode 100644 index c94ba0d..0000000 --- a/man/CatVars.Rd +++ /dev/null @@ -1,11 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/eal_4_CatVars.R -\name{CatVars} -\alias{CatVars} -\title{Geographic coverage} -\usage{ -CatVars(input, output, session, save.variable, main.env, NSB) -} -\description{ -UI part for the Geographic Coverage module -} diff --git a/man/CatVarsUI.Rd b/man/CatVarsUI.Rd deleted file mode 100644 index 7b9a5c8..0000000 --- a/man/CatVarsUI.Rd +++ /dev/null @@ -1,11 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/eal_4_CatVars.R -\name{CatVarsUI} -\alias{CatVarsUI} -\title{Geographic coverage} -\usage{ -CatVarsUI(id, title, dev) -} -\description{ -UI part for the Geographic Coverage module -} diff --git a/man/DataFiles.Rd b/man/DataFiles.Rd deleted file mode 100644 index d7b321c..0000000 --- a/man/DataFiles.Rd +++ /dev/null @@ -1,11 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/eal_2_DataFiles.R -\name{DataFiles} -\alias{DataFiles} -\title{Data Package files} -\usage{ -DataFiles(input, output, session, save.variable, main.env, NSB) -} -\description{ -server part of the DataFiles module. -} diff --git a/man/DataFilesUI.Rd b/man/DataFilesUI.Rd deleted file mode 100644 index 2506882..0000000 --- a/man/DataFilesUI.Rd +++ /dev/null @@ -1,11 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/eal_2_DataFiles.R -\name{DataFilesUI} -\alias{DataFilesUI} -\title{Data Package files} -\usage{ -DataFilesUI(id, dev = FALSE) -} -\description{ -UI part of the DataFiles module. -} diff --git a/man/EMLAL.Rd b/man/EMLAL.Rd deleted file mode 100644 index a0fa9bd..0000000 --- a/man/EMLAL.Rd +++ /dev/null @@ -1,12 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/eal_0.R -\name{EMLAL} -\alias{EMLAL} -\title{EMLAL} -\usage{ -EMLAL(input, output, session, save.variable, main.env) -} -\description{ -server part of the EMLAL module. Allow the user to use a front-end shiny interface to the EML Assembly Line package, from -Environmental Data Initiative. -} diff --git a/man/EMLALUI.Rd b/man/EMLALUI.Rd deleted file mode 100644 index 95bda46..0000000 --- a/man/EMLALUI.Rd +++ /dev/null @@ -1,12 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/eal_0.R -\name{EMLALUI} -\alias{EMLALUI} -\title{EMLALUI} -\usage{ -EMLALUI(id, dev = FALSE) -} -\description{ -UI part of the EMLAL module. Allow the user to use a front-end shiny interface to the EML Assembly Line package, from -Environmental Data Initiative. ARAR -} diff --git a/man/GeoCov.Rd b/man/GeoCov.Rd deleted file mode 100644 index c71fcf1..0000000 --- a/man/GeoCov.Rd +++ /dev/null @@ -1,11 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/eal_5_geographicCoverage.R -\name{GeoCov} -\alias{GeoCov} -\title{Geographic coverage} -\usage{ -GeoCov(input, output, session, save.variable, main.env, NSB) -} -\description{ -server part for the Geographic Coverage module -} diff --git a/man/GeoCovInputUI.Rd b/man/GeoCovInputUI.Rd deleted file mode 100644 index 52c8c20..0000000 --- a/man/GeoCovInputUI.Rd +++ /dev/null @@ -1,20 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/eal_5_GeoCovInput.R -\name{GeoCovInputUI} -\alias{GeoCovInputUI} -\alias{GeoCovInput} -\title{Geographic coverage modular Input} -\usage{ -GeoCovInputUI(id, site.id, rmv.id, default = NULL) - -GeoCovInput(input, output, session, rv, rmv.id, site.id, ref) -} -\description{ -UI part for the Geographic Coverage modular input, used -in Geographic Coverage module to input a custom entry in the dataset. -} -\section{Functions}{ -\itemize{ -\item \code{GeoCovInput}: -}} - diff --git a/man/GeoCovUI.Rd b/man/GeoCovUI.Rd deleted file mode 100644 index 6161e97..0000000 --- a/man/GeoCovUI.Rd +++ /dev/null @@ -1,11 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/eal_5_geographicCoverage.R -\name{GeoCovUI} -\alias{GeoCovUI} -\title{Geographic coverage} -\usage{ -GeoCovUI(id, title, dev) -} -\description{ -UI part for the Geographic Coverage module -} diff --git a/man/MakeEMLUI.Rd b/man/MakeEMLUI.Rd deleted file mode 100644 index d8d385f..0000000 --- a/man/MakeEMLUI.Rd +++ /dev/null @@ -1,21 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/eal_9_makeeml.R -\name{MakeEMLUI} -\alias{MakeEMLUI} -\alias{MakeEML} -\title{MakeEMLUI} -\usage{ -MakeEMLUI(id, title, dev) - -MakeEML(input, output, session, save.variable, main.env) -} -\description{ -UI part for the Make EML module - -server part of the make EML module -} -\section{Functions}{ -\itemize{ -\item \code{MakeEML}: -}} - diff --git a/man/MiscUI.Rd b/man/MiscUI.Rd deleted file mode 100644 index 7d45d6a..0000000 --- a/man/MiscUI.Rd +++ /dev/null @@ -1,19 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/eal_8_misc.R -\name{MiscUI} -\alias{MiscUI} -\alias{Misc} -\title{MiscUI} -\usage{ -MiscUI(id, title, dev, save.variable) - -Misc(input, output, session, save.variable, main.env, NSB) -} -\description{ -UI for "last but not least" module -} -\section{Functions}{ -\itemize{ -\item \code{Misc}: -}} - diff --git a/man/Miscellaneous.Rd b/man/Miscellaneous.Rd deleted file mode 100644 index 335253b..0000000 --- a/man/Miscellaneous.Rd +++ /dev/null @@ -1,11 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/eal_8_miscellaneous.R -\name{Miscellaneous} -\alias{Miscellaneous} -\title{Miscellaneous} -\usage{ -Miscellaneous(input, output, session, save.variable, rv) -} -\description{ -Miscellaneous -} diff --git a/man/MiscellaneousUI.Rd b/man/MiscellaneousUI.Rd deleted file mode 100644 index 4f55efd..0000000 --- a/man/MiscellaneousUI.Rd +++ /dev/null @@ -1,11 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/eal_8_miscellaneous.R -\name{MiscellaneousUI} -\alias{MiscellaneousUI} -\title{MiscellaneousUI} -\usage{ -MiscellaneousUI(id, help.label = NULL, value = "") -} -\description{ - -} diff --git a/man/Personnel.Rd b/man/Personnel.Rd deleted file mode 100644 index 75a1e5c..0000000 --- a/man/Personnel.Rd +++ /dev/null @@ -1,11 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/eal_7_personnel.R -\name{Personnel} -\alias{Personnel} -\title{Personnel} -\usage{ -Personnel(input, output, session, save.variable, main.env, NSB) -} -\description{ -server part of Personnel module -} diff --git a/man/PersonnelModUI.Rd b/man/PersonnelModUI.Rd deleted file mode 100644 index 9b62072..0000000 --- a/man/PersonnelModUI.Rd +++ /dev/null @@ -1,30 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/eal_7_personnel.R -\name{PersonnelModUI} -\alias{PersonnelModUI} -\alias{PersonnelMod} -\title{PersonnelModUI} -\usage{ -PersonnelModUI(id, div.id, site.id, rmv.id, role = NULL, saved = NULL) - -PersonnelMod( - input, - output, - session, - main.env, - rv, - rmv.id, - site.id, - ref, - role = NULL, - saved = NULL -) -} -\description{ -module to document EML Personnel -} -\section{Functions}{ -\itemize{ -\item \code{PersonnelMod}: -}} - diff --git a/man/PersonnelUI.Rd b/man/PersonnelUI.Rd deleted file mode 100644 index 022a35d..0000000 --- a/man/PersonnelUI.Rd +++ /dev/null @@ -1,11 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/eal_7_personnel.R -\name{PersonnelUI} -\alias{PersonnelUI} -\title{PersonnelUI} -\usage{ -PersonnelUI(id, title, dev) -} -\description{ -PersonnelUI -} diff --git a/man/SelectDP.Rd b/man/SelectDP.Rd deleted file mode 100644 index 45c356c..0000000 --- a/man/SelectDP.Rd +++ /dev/null @@ -1,12 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/eal_1_SelectDP.R -\name{SelectDP} -\alias{SelectDP} -\title{Data Package selection} -\usage{ -SelectDP(input, output, session, save.variable, main.env) -} -\description{ -UI part for the Data Package selection. Allow the user to choose between -creating a new data package or loading an existing one. -} diff --git a/man/SelectDPUI.Rd b/man/SelectDPUI.Rd deleted file mode 100644 index c4cda88..0000000 --- a/man/SelectDPUI.Rd +++ /dev/null @@ -1,20 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/eal_1_SelectDP.R -\name{SelectDPUI} -\alias{SelectDPUI} -\alias{loadFromDP} -\title{Data Package selection} -\usage{ -SelectDPUI(id, width = 12, dev = FALSE) - -loadFromDP(save.variable, file) -} -\description{ -UI part for the Data Package selection. Allow the user to choose between -creating a new data package or loading an existing one. -} -\section{Functions}{ -\itemize{ -\item \code{loadFromDP}: Sets up a DP from a pre-written EML file. -}} - diff --git a/man/TaxCov.Rd b/man/TaxCov.Rd deleted file mode 100644 index 46151ce..0000000 --- a/man/TaxCov.Rd +++ /dev/null @@ -1,11 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/eal_6_taxonomicCoverage.R -\name{TaxCov} -\alias{TaxCov} -\title{Taxonomic coverage} -\usage{ -TaxCov(input, output, session, save.variable, main.env, NSB) -} -\description{ -server part for the Taxonomic Coverage module -} diff --git a/man/TaxCovUI.Rd b/man/TaxCovUI.Rd deleted file mode 100644 index 2de741c..0000000 --- a/man/TaxCovUI.Rd +++ /dev/null @@ -1,11 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/eal_6_taxonomicCoverage.R -\name{TaxCovUI} -\alias{TaxCovUI} -\title{Taxonomic coverage} -\usage{ -TaxCovUI(id, title, dev) -} -\description{ -UI part for the Taxonomic Coverage module -} diff --git a/man/URL_Input_UI.Rd b/man/URL_Input_UI.Rd index b3794b5..553bb84 100644 --- a/man/URL_Input_UI.Rd +++ b/man/URL_Input_UI.Rd @@ -7,7 +7,15 @@ \usage{ URL_Input_UI(id, label = "URL", width = "100\%") -URL_Input(input, output, session) +URL_Input(id) +} +\arguments{ +\item{id}{(character) shiny module inputId.} + +\item{label}{(character) display label for the control, or NULL for no label.} + +\item{width}{(character) the width of the input, e.g. '400px', or '100%'; see +validateCssUnit().} } \value{ (output of `callModule`) If input is a valid URL (regex-tested + curl-tested), returns input. diff --git a/man/about.Rd b/man/about.Rd deleted file mode 100644 index 1bcdb77..0000000 --- a/man/about.Rd +++ /dev/null @@ -1,11 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/about-module.R -\name{about} -\alias{about} -\title{about} -\usage{ -about(input, output, session) -} -\description{ -server part of the about module. -} diff --git a/man/aboutUI.Rd b/man/aboutUI.Rd deleted file mode 100644 index 5d481b3..0000000 --- a/man/aboutUI.Rd +++ /dev/null @@ -1,11 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/aboutUI-module.R -\name{aboutUI} -\alias{aboutUI} -\title{aboutUI} -\usage{ -aboutUI(id) -} -\description{ -UI part of the about module. -} diff --git a/man/checkTruth.Rd b/man/checkTruth.Rd index da8e1ce..ff2dec7 100644 --- a/man/checkTruth.Rd +++ b/man/checkTruth.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/fill-module_functions.R +% Please edit documentation in R/utils-checkTruth.R \name{checkTruth} \alias{checkTruth} \title{checkTruth} @@ -8,8 +8,6 @@ checkTruth(x) } \arguments{ \item{x}{argument to check fo truthiness} - -\item{output}{what to return if `x` is not truthy} } \description{ check if `x` is truthy (as shiny::isTruthy) or not. diff --git a/man/collapsibleUI.Rd b/man/collapsibleUI.Rd index 385922c..bc523d1 100644 --- a/man/collapsibleUI.Rd +++ b/man/collapsibleUI.Rd @@ -2,14 +2,13 @@ % Please edit documentation in R/utils-collapsible.R \name{collapsibleUI} \alias{collapsibleUI} -\alias{collapsible} \title{collapsibleUI} \usage{ collapsibleUI(id, label, .hidden = TRUE, ..., class = NULL) - -collapsible(input, output, session) } \arguments{ +\item{id}{character. The input slot that will be used to access the value.} + \item{label}{character. A label appearing on the clickable link.} \item{.hidden}{logical. A flag to make the UI display as collapsed or not.} @@ -21,8 +20,3 @@ collapsible(input, output, session) \description{ A shiny module to get a div collapsed by clicking on a link. } -\section{Functions}{ -\itemize{ -\item \code{collapsible}: -}} - diff --git a/man/describeWorkflowUI.Rd b/man/describeWorkflowUI.Rd deleted file mode 100644 index 85c5e3b..0000000 --- a/man/describeWorkflowUI.Rd +++ /dev/null @@ -1,21 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/upload-module_functions.R -\name{describeWorkflowUI} -\alias{describeWorkflowUI} -\alias{describeWorkflow} -\title{describeWorkflowUI} -\usage{ -describeWorkflowUI(id, sources, targets) - -describeWorkflow(input, output, session) -} -\description{ -UI part of the script-data workflow-describing linking module (in upload). - -server part of the script-data workflow-describing linking module (in upload). -} -\section{Functions}{ -\itemize{ -\item \code{describeWorkflow}: -}} - diff --git a/man/docUI.Rd b/man/docUI.Rd deleted file mode 100644 index 9afceed..0000000 --- a/man/docUI.Rd +++ /dev/null @@ -1,11 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/documentation-module.R -\name{docUI} -\alias{docUI} -\title{docUI} -\usage{ -docUI(id) -} -\description{ -UI part of the documentation module -} diff --git a/man/documentation.Rd b/man/documentation.Rd deleted file mode 100644 index 5ca5e68..0000000 --- a/man/documentation.Rd +++ /dev/null @@ -1,11 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/documentation-module.R -\name{documentation} -\alias{documentation} -\title{documentation} -\usage{ -documentation(input, output, session) -} -\description{ -server part of the documentation module. -} diff --git a/man/dot-app_server.Rd b/man/dot-app_server.Rd deleted file mode 100644 index b5405ee..0000000 --- a/man/dot-app_server.Rd +++ /dev/null @@ -1,11 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/server.R -\name{.app_server} -\alias{.app_server} -\title{.app_server} -\usage{ -.app_server(input, output, session) -} -\description{ -server part for the app's main script. -} diff --git a/man/dot-app_ui.Rd b/man/dot-app_ui.Rd deleted file mode 100644 index 3eabc7a..0000000 --- a/man/dot-app_ui.Rd +++ /dev/null @@ -1,11 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/ui.R -\name{.app_ui} -\alias{.app_ui} -\title{.app_ui} -\usage{ -.app_ui() -} -\description{ -UI part of the mainapp's script -} diff --git a/man/dot-globalScript.Rd b/man/dot-globalScript.Rd deleted file mode 100644 index b1e8100..0000000 --- a/man/dot-globalScript.Rd +++ /dev/null @@ -1,11 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/headerScript.R -\name{.globalScript} -\alias{.globalScript} -\title{.globalScript} -\usage{ -.globalScript(dev = FALSE) -} -\description{ -script to generate `globals` reactiveValues -} diff --git a/man/dot-headerScript.Rd b/man/dot-headerScript.Rd deleted file mode 100644 index b02f0a3..0000000 --- a/man/dot-headerScript.Rd +++ /dev/null @@ -1,11 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/headerScript.R -\name{.headerScript} -\alias{.headerScript} -\title{.headerScript} -\usage{ -.headerScript() -} -\description{ -Misc preparations commands -} diff --git a/man/extractCoordinates.Rd b/man/extractCoordinates.Rd deleted file mode 100644 index 1989156..0000000 --- a/man/extractCoordinates.Rd +++ /dev/null @@ -1,11 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/eal_5_GeoCovInput.R -\name{extractCoordinates} -\alias{extractCoordinates} -\title{extractCoordinates} -\usage{ -extractCoordinates(rv, coord.cols, .pattern, files.data) -} -\description{ -extractCoordinates -} diff --git a/man/fillUI.Rd b/man/fillUI.Rd deleted file mode 100644 index ccdafdc..0000000 --- a/man/fillUI.Rd +++ /dev/null @@ -1,19 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/fill-module.R -\name{fillUI} -\alias{fillUI} -\alias{fill} -\title{Fill} -\usage{ -fillUI(id, dev = FALSE) - -fill(input, output, session, main.env) -} -\description{ -server part of the fill module. Root script for whole module (comprise EML AL and MetaFIN) -} -\section{Functions}{ -\itemize{ -\item \code{fill}: -}} - diff --git a/man/followPath.Rd b/man/followPath.Rd index 9bc5cdc..df638e9 100644 --- a/man/followPath.Rd +++ b/man/followPath.Rd @@ -1,12 +1,9 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/documentation-module_functions.R, -% R/utils-followPath.R +% Please edit documentation in R/utils-followPath.R \name{followPath} \alias{followPath} \title{followPath} \usage{ -followPath(tree, path, sep = "/", root = "root") - followPath(tree, path, sep = "/", root = "root") } \arguments{ @@ -19,17 +16,7 @@ separated with sep} \item{root}{if your path has a root name for root node, enter its name here. Else, enter NULL.} - -\item{tree:}{explored hierarchy list thanks to @path} - -\item{path:}{vector of characters matching some of @tree names and -separated with sep} - -\item{sep:}{separators between path elements (aka @tree names)} } \description{ -Takes a hierarchy list (tree), a path written in a vector pasted -with sep = sep, and returns the targetted node - Takes a hierarchy list (tree), a path written in a vector pasted with sep, and returns the leaf } diff --git a/man/initReactive.Rd b/man/initReactive.Rd deleted file mode 100644 index cbbba2b..0000000 --- a/man/initReactive.Rd +++ /dev/null @@ -1,27 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/fill-module_functions.R -\name{initReactive} -\alias{initReactive} -\alias{saveReactive} -\title{initReactive} -\usage{ -initReactive(sub.list = NULL, save.variable = NULL, main.env) - -saveReactive(save.variable, rv = NULL, main.env = NULL) -} -\arguments{ -\item{sub.list}{either NULL, "emlal", "metafin" to precise which sub.list to initialize (NULL initializes the whole variable)} -} -\value{ -`save.variable` modified. -} -\description{ -EMLAL module specific function. Initialize `save.variable` variable. - -save the `save.variable` variable at wanted location -} -\section{Functions}{ -\itemize{ -\item \code{saveReactive}: -}} - diff --git a/man/insertGeoCovInput.Rd b/man/insertGeoCovInput.Rd deleted file mode 100644 index 845614b..0000000 --- a/man/insertGeoCovInput.Rd +++ /dev/null @@ -1,12 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/eal_5_GeoCovInput.R -\name{insertGeoCovInput} -\alias{insertGeoCovInput} -\title{insertGeoCovInput} -\usage{ -insertGeoCovInput(id, rv, ns, default = NULL) -} -\description{ -Leads all the process of rendering a GeoCovInput -GUI and its associated server -} diff --git a/man/insertPersonnelInput.Rd b/man/insertPersonnelInput.Rd deleted file mode 100644 index 9b2330a..0000000 --- a/man/insertPersonnelInput.Rd +++ /dev/null @@ -1,13 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/eal_7_personnel.R -\name{insertPersonnelInput} -\alias{insertPersonnelInput} -\title{insertPersonnelInput} -\usage{ -insertPersonnelInput(id, rv, ns, main.env, role = NULL, saved = NULL) -} -\description{ -helper function to insert PersonnelMod* functions. Calling this from -a shiny server will insert PersonnelModUI and create its server part. Provided with -features to delete them. -} diff --git a/man/listReactiveValues.Rd b/man/listReactiveValues.Rd index aa85950..93f4fa4 100644 --- a/man/listReactiveValues.Rd +++ b/man/listReactiveValues.Rd @@ -10,8 +10,10 @@ listReactiveValues(rv, lv = 0, name = "root") \item{rv}{reactiveValues to turn into list} \item{lv}{(verbose purposes)} + +\item{name}{root node name} } \description{ -Allows to turn a `reactiveValues`` object -into a list. Uses recursive method. +Allows to turn a `reactiveValues`` object into a list. Uses +recursive method. } diff --git a/man/markdownInputUI.Rd b/man/markdownInputUI.Rd index 5077f6b..59644b8 100644 --- a/man/markdownInputUI.Rd +++ b/man/markdownInputUI.Rd @@ -5,21 +5,17 @@ \alias{markdownInput} \title{markdownInputUI} \usage{ -markdownInputUI( - inputId, - label = "Text", - icon = TRUE, - preview = FALSE, - value = "" -) +markdownInputUI(id, label = "Text", icon = TRUE, preview = FALSE, value = "") -markdownInput(input, output, session, preview = FALSE) +markdownInput(id, preview = FALSE) } \arguments{ -\item{inputId}{character. The input slot that will be used to access the value.} +\item{id}{character. The input slot that will be used to access the value.} \item{label}{character. Display label for the control, or NULL for no label.} +\item{icon}{character. An optional `icon()` to appear on the button.} + \item{preview}{logical. Shall a preview panel appear? (right-sided, 50\% width)} \item{value}{character. Initial value of the text input (default to "")} diff --git a/man/navSidebar.Rd b/man/navSidebar.Rd deleted file mode 100644 index 057da37..0000000 --- a/man/navSidebar.Rd +++ /dev/null @@ -1,42 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/eal_0_functions.R -\name{navSidebar} -\alias{navSidebar} -\alias{onQuit} -\alias{onSave} -\alias{nextTab} -\alias{prevTab} -\title{navSidebar} -\usage{ -navSidebar(id, main.env, save.variable) - -onQuit(input, output, session, main.env, save.variable, NSB) - -onSave(input, output, session, save.variable, NSB) - -nextTab(input, output, session, main.env, save.variable, NSB) - -prevTab(input, output, session, main.env, NSB) -} -\arguments{ -\item{id}{shiny server id} - -\item{main.env}{MetaShARK main.env variable} - -\item{save.variable}{MetaShARK savevar variable} -} -\description{ -server part for shiny navigation sidebar module (see [navSidebar()]). -The functions are very specific and thus are not exported. -} -\section{Functions}{ -\itemize{ -\item \code{onQuit}: - -\item \code{onSave}: - -\item \code{nextTab}: - -\item \code{prevTab}: -}} - diff --git a/man/navSidebarUI.Rd b/man/navSidebarUI.Rd deleted file mode 100644 index 633e543..0000000 --- a/man/navSidebarUI.Rd +++ /dev/null @@ -1,50 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/eal_0_functions.R -\name{navSidebarUI} -\alias{navSidebarUI} -\alias{quitButton} -\alias{saveButton} -\alias{nextTabButton} -\alias{prevTabButton} -\title{navSidebarUI} -\usage{ -navSidebarUI(id, class = "navSidebar", .prev = TRUE, .next = TRUE) - -quitButton(id) - -saveButton(id) - -nextTabButton(id) - -prevTabButton(id) -} -\arguments{ -\item{id}{shiny id} - -\item{class}{css class style. Default is set to "navSidebar": -.navSidebar { - width: 100%; - text-align: center; - padding: 0; -}} - -\item{.prev}{logical. Do you want a "Previous" actionButton? (prevTabButton)} - -\item{.next}{logical. Do you want a "Next" actionButton? (nextTabButton)} - -\item{...}{UI tags set at the bottom of the navigation side bar} -} -\description{ -UI part for shiny navigation sidebar module -} -\section{Functions}{ -\itemize{ -\item \code{quitButton}: - -\item \code{saveButton}: - -\item \code{nextTabButton}: - -\item \code{prevTabButton}: -}} - diff --git a/man/readPlainText.Rd b/man/readPlainText.Rd index 27e28cb..e349889 100644 --- a/man/readPlainText.Rd +++ b/man/readPlainText.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/fill-module_functions.R +% Please edit documentation in R/utils-readPlaintext.R \name{readPlainText} \alias{readPlainText} \title{readFilesText} diff --git a/man/settings.Rd b/man/settings.Rd index 2399e1d..12efeac 100644 --- a/man/settings.Rd +++ b/man/settings.Rd @@ -4,7 +4,7 @@ \alias{settings} \title{settings} \usage{ -settings(input, output, session, main.env) +settings(id, main.env) } \description{ server part of the settings module. Allow the user to change several settings in the app. diff --git a/man/uploadUI.Rd b/man/uploadUI.Rd index c94b49f..9c2b522 100644 --- a/man/uploadUI.Rd +++ b/man/uploadUI.Rd @@ -7,7 +7,7 @@ \usage{ uploadUI(id, main.env) -upload(input, output, session, main.env) +upload(id, main.env) } \arguments{ \item{id}{shiny module id} diff --git a/man/withRedStar.Rd b/man/withRedStar.Rd index 5c0f686..7188c4e 100644 --- a/man/withRedStar.Rd +++ b/man/withRedStar.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/golem_utils_ui.R +% Please edit documentation in R/utils_withRedStar.R \name{withRedStar} \alias{withRedStar} \title{withRedStar}