Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Repair RStudio add-in #101

Merged
merged 5 commits into from
Feb 11, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,16 @@ License: GPL-3
Encoding: UTF-8
LazyData: true
Suggests:
bookdown,
clipr,
covr,
maelle marked this conversation as resolved.
Show resolved Hide resolved
covrpage,
mockery,
revealjs,
shinyFiles,
testthat,
xaringan,
tufte,
bookdown,
revealjs,
mockery
xaringan
VignetteBuilder: knitr
Imports:
devtools,
Expand Down
246 changes: 206 additions & 40 deletions R/shinyGadget.R
Original file line number Diff line number Diff line change
@@ -1,65 +1,199 @@
projectGadget <- function() {
if (!requireNamespace("shinyFiles", quietly = TRUE)) {
stop("The shinyFiles package is required for this gadget to work. Please install it.",
call. = FALSE
)
}

if (!requireNamespace("clipr", quietly = TRUE)) {
stop("The clipr package is required for this gadget to work. Please install it.",
call. = FALSE
)
}

ui <- miniUI::miniPage(
miniUI::gadgetTitleBar("Create pRoject"),
miniUI::gadgetTitleBar("Create Project"),
miniUI::miniContentPanel(
shiny::tags$style("#folder {width: 210px; };",
type = "text/css"
),
# Custom shiny to javascript binding
# scrolls "content" to bottom once called
shiny::tags$script(
"Shiny.addCustomMessageHandler('scrollCallback',
function(x) {
var content = document.getElementsByClassName('gadget-scroll')[0];
content.scrollTop = content.scrollHeight - content.clientHeight;
}
);"
),
shiny::inputPanel(
shiny::selectInput(
"projectType",
label = "Project Type",
choices = c("Basic", "Analysis", "Package", "Training"),
choices = c("Basic", "Package", "Analysis", "Training"),
selected = "Basic"
),
shiny::textInput("name", "Project Name")
shiny::tags$div(
title = "A badge from repostatus.org will be added to the README.",
shiny::selectInput(
"initial_status",
label = "Initial Status",
choices = statuses()$status,
selected = "wip"
)
),
shiny::tags$div(
title = "This will be used as the name for the project.",
shiny::textInput("name", "Project Name", value = NULL)
),
shiny::tags$div(
title = "A description of what the project does.",
shiny::textInput("title", "Project Title", value = NULL)
),
shiny::div("Project Folder", class = "control-label", style = "font-weight: bold;"),
shiny::br(),
shinyFiles::shinyDirButton("folder",
label = "Choose Folder",
title = "Please choose a project folder",
class = "btn-primary"
),
shiny::uiOutput("folder")
),
shiny::uiOutput("ui"),
shiny::conditionalPanel(
condition = "input.projectType != 'Package'",
condition = "input.externalSetup",
maelle marked this conversation as resolved.
Show resolved Hide resolved
shiny::inputPanel(
shiny::h4("Best Practices"),
shiny::br(),
shiny::checkboxInput("git", "Use Git", value = TRUE),
shiny::checkboxInput("travis", "Use Travis", value = TRUE),
shiny::selectInput("packagedeps",
label = "Use a package for handling reproducibility",
choices = c("none", "packrat", "checkpoint"),
selected = "packrat"
)
shiny::radioButtons("git_service",
label = "Git Service",
choices = "GitHub"
),
shiny::radioButtons("private",
label = "Repository",
choices = c("public" = FALSE, "private" = TRUE)
),
shiny::radioButtons("protocol",
label = "Protocol",
choices = c("ssh", "http"),
select = "ssh"
),
shiny::radioButtons("ci_activation",
label = "Continuous Integration",
choices = c("none" = "", "travis")
),
shiny::textInput("login", label = "Login", value = gh::gh_whoami()$login)
)
)
)
)

server <- function(input, output, session) {

# Call custom javascript to scroll window
observeEvent(input$externalSetup,
if(input$externalSetup) session$sendCustomMessage(type = "scrollCallback", 1)
)

volumes <- c(
maelle marked this conversation as resolved.
Show resolved Hide resolved
"Working Directory" = getwd(),
Home = fs::path_home(),
shinyFiles::getVolumes()()
)

shinyFiles::shinyDirChoose(
input, "folder",
roots = volumes, session = session,
restrictions = system.file(package = "base")
)

folder <- shiny::reactive({
folder <- shinyFiles::parseDirPath(volumes, input$folder)
if (length(folder) == 0) {
folder <- getwd()
}
folder
})

output$folder <- shiny::renderUI({
shiny::textInput("folder", NULL,
value = folder()
)
})

output$ui <- shiny::renderUI({
switch(input$projectType,

"Basic" = shiny::div(),
"Basic" = shiny::inputPanel(
shiny::checkboxInput("git", "Use Git", value = TRUE),
shiny::tags$div(
title = "This will reset the active RStudio project after setup completes",
shiny::checkboxInput("reset", "Reset Project", value = TRUE)
),
shiny::checkboxInput("externalSetup", label = "External Setup", value = FALSE),
shiny::br(),
shiny::radioButtons("packagedeps",
label = "Dependency Management",
choices = okpackagedeps(),
selected = "checkpoint"
)
),
"Analysis" = shiny::inputPanel(
shiny::checkboxInput("git", "Use Git", value = TRUE),
shiny::tags$div(
title = "This will reset the active RStudio project after setup completes",
shiny::checkboxInput("reset", "Reset Project", value = TRUE)
),
shiny::checkboxInput("externalSetup", label = "External Setup", value = FALSE),
shiny::br(),
shiny::selectInput("dirs",
label = "Directories",
choices = c("data", "analysis", "output"),
selected = c("data", "analysis", "output"),
multiple = TRUE
),
shiny::radioButtons("packagedeps",
label = "Dependency Management",
choices = okpackagedeps(),
selected = "checkpoint"
)
),
"Package" = shiny::inputPanel(
shiny::h4("Best Practice"),
shiny::br(),
shiny::checkboxInput("git", "Use Git", value = TRUE),
shiny::tags$div(
title = "This will reset the active RStudio project after setup completes",
shiny::checkboxInput("reset", "Reset Project", value = TRUE)
),
shiny::checkboxInput("externalSetup", label = "External Setup", value = FALSE),
shiny::br(),
shiny::conditionalPanel(
shiny::selectInput("coverage",
label = "Code Coverage",
choices = c("codecov", "coveralls")
)
shiny::radioButtons("coverage",
label = "Code Coverage",
choices = c("codecov", "coveralls"),
selected = "codecov"
),
shiny::radioButtons("pkgdown",
label = "Add pkgdown config",
choices = c("Yes" = TRUE, "No" = FALSE)
)
),
"Training" = shiny::inputPanel(
shiny::checkboxInput("git", "Use Git", value = TRUE),
shiny::tags$div(
title = "This will reset the active RStudio project after setup completes",
shiny::checkboxInput("reset", "Reset Project", value = TRUE)
),
shiny::checkboxInput("externalSetup", label = "External Setup", value = FALSE),
shiny::br(),
shiny::selectInput("dirs",
label = "Directories",
choices = c("data", "handouts", "slides"),
selected = c("data", "handouts", "slides"),
multiple = TRUE
),
shiny::radioButtons("packagedeps",
label = "Dependency Management",
choices = okpackagedeps(),
selected = "checkpoint"
),
shiny::radioButtons("handoutE",
label = "Handouts",
choices = c("rmarkdown", "bookdown", "tufte"),
Expand All @@ -75,35 +209,67 @@ projectGadget <- function() {
})

shiny::observeEvent(input$done, {
shiny::stopApp()

switch(input$projectType,

"Basic" = createBasicProject(
name = input$name,
git = input$git,
packagedeps = input$packagedeps
"Basic" = capture(
call("createBasicProject",
name = input$name,
title = empty_as_null(input$title),
folder = as.character(folder()),
initial_status = input$initial_status,
packagedeps = input$packagedeps,
git = input$git,
external_setup = ext_setup(input),
reset = input$reset
)
),

"Analysis" = createAnalysisProject(
name = input$name, dirs = input$dirs,
git = input$git,
packagedeps = input$packagedeps
"Analysis" = capture(
call("createAnalysisProject",
name = input$name,
title = empty_as_null(input$title),
folder = as.character(folder()),
initial_status = input$initial_status,
dirs = input$dirs,
git = input$git,
packagedeps = input$packagedeps,
external_setup = ext_setup(input),
reset = input$reset
)
),

"Package" = createPackageProject(
name = input$name,
coverage = input$coverage
"Package" = capture(
call("createPackageProject",
name = input$name,
title = empty_as_null(input$title),
folder = as.character(folder()),
initial_status = input$initial_status,
coverage = input$coverage,
git = input$git,
pkgdown = input$pkgdown,
external_setup = ext_setup(input),
reset = input$reset
)
),

"Training" = createTrainingProject(
name = input$name, dirs = input$dirs,
handoutEngine = input$handoutE,
slideEngine = input$slideE,
git = input$git,
packagedeps = input$packagedeps
"Training" = capture(
call("createTrainingProject",
name = input$name,
title = empty_as_null(input$title),
folder = as.character(folder()),
initial_status = input$initial_status,
dirs = input$dirs,
handoutEngine = input$handoutE,
slideEngine = input$slideE,
git = input$git,
packagedeps = input$packagedeps,
external_setup = ext_setup(input),
reset = input$reset
)
)
)

shiny::stopApp()
})
}

Expand Down
39 changes: 39 additions & 0 deletions R/utils.R
Original file line number Diff line number Diff line change
Expand Up @@ -163,3 +163,42 @@ gh_retry <- function(quoted_expression){
}
return(ok)
}

#####################################
# Process inputs in shiny gadget
#####################################

#' Treat empty string as NULL
#' @noRd
empty_as_null <- function(arg) {
if(arg == "") return(NULL)
arg
}

#' Create config list for external_setup
#' @noRd
ext_setup <- function(input) {
if(!input$externalSetup) {
NULL
} else {
list(
git_service = input$git_service,
private = input$private,
protocol = input$protocol,
login = input$login,
ci_activation = ifelse(input$ci_activation == "", NULL, input$ci_activation)
)
}
}

#' Capture expression, write to clipboard, evaluate & output as message
#' @noRd
capture <- function(x) {
str_x <- deparse(x)
eval(x)
message(
"The starters function call is shown below and has been copied to the clipboard:\n\n",
str_x
)
clipr::write_clip(str_x)
}