Required classes for our style of building/running shiny applications (no documentation)
This commit is contained in:
143
R/frameApplication.R
Normal file
143
R/frameApplication.R
Normal file
@@ -0,0 +1,143 @@
|
||||
|
||||
#' @export
|
||||
FrameApplication <- R6::R6Class(
|
||||
"FrameApplication",
|
||||
public = list(
|
||||
initialize = function(appPage = NULL, language = NULL) {
|
||||
if (!is.null(appPage)) {
|
||||
private$appPage <- appPage
|
||||
} else {
|
||||
private$appPage <- modules::use("pages/application.R")
|
||||
}
|
||||
if (!is.null(language)) {
|
||||
private$language <- language
|
||||
}
|
||||
invisible(self)
|
||||
},
|
||||
withSessionLogger = function(sessionLogger) {
|
||||
if (!inherits(sessionLogger, "SessionLogger")) {
|
||||
rlang::abort("sessionLogger is not an instance of SessionLogger class")
|
||||
}
|
||||
private$sessionLogger <- sessionLogger
|
||||
invisible(self)
|
||||
},
|
||||
withBootstrap4Shim = function() {
|
||||
private$withBS4 <- TRUE
|
||||
invisible(self)
|
||||
},
|
||||
getSessionDBClient = function(
|
||||
session, db_config = NULL, allowFailure = FALSE
|
||||
) {
|
||||
# Check DBClient package is installed
|
||||
if (!rlang::is_installed("AVSDevR.DBClient")) {
|
||||
return(NULL)
|
||||
}
|
||||
|
||||
# Check connection configuration is available
|
||||
db_conn <- AVSDevR.DBClient::DBConnection$new()
|
||||
if (is.null(db_config)) {
|
||||
if (!db_conn$loadConfiguration(TRUE)) {
|
||||
return(NULL)
|
||||
}
|
||||
} else {
|
||||
db_conn$configure(db_config)
|
||||
}
|
||||
|
||||
# Try and connect
|
||||
if (!db_conn$connect()) {
|
||||
if (allowFailure) {
|
||||
rlang::abort(
|
||||
"Failed to connect to database - database not available or not \
|
||||
created"
|
||||
)
|
||||
}
|
||||
return(NULL)
|
||||
}
|
||||
db_conn$disconnectOnSessionEnd(session)
|
||||
|
||||
# Create the client instance
|
||||
AVSDevR.DBClient::DBClient$new(db_conn)
|
||||
},
|
||||
ui = function() {
|
||||
if (file.exists("widgets/menu.R")) {
|
||||
# Multi-frame application
|
||||
frame <- do.call(tabItems, private$appPage$tabs("application"))
|
||||
frame_tabs <- sapply(frame$children, function(tab) {
|
||||
tab$attr$`data-tabName`
|
||||
})
|
||||
|
||||
menu <- modules::use("widgets/menu.R")
|
||||
menu_tabs <- unname(sapply(
|
||||
menu$ui, function(ti) {
|
||||
ti$children[[1]]$attr$`data-value`
|
||||
}
|
||||
))
|
||||
|
||||
if (!identical(sort(menu_tabs), sort(frame_tabs))) {
|
||||
rlang::abort(
|
||||
"Tab names in widgets/menu.R do not match tab names in \
|
||||
pages/application.R!"
|
||||
)
|
||||
}
|
||||
} else {
|
||||
# Single frame application
|
||||
frame <- shiny::fluidPage(
|
||||
title = private$appPage$title(),
|
||||
private$appPage$ui("application")
|
||||
)
|
||||
}
|
||||
|
||||
ui <- shiny::tagList(
|
||||
shiny::tags$head(
|
||||
shiny::singleton(
|
||||
shinyjs::useShinyjs(debug = getOption("debug.shinyjs", FALSE))
|
||||
)
|
||||
),
|
||||
frame,
|
||||
if (rlang::is_installed("AVSDevR.ShinyDisconnectHandler")) {
|
||||
AVSDevR.ShinyDisconnectHandler::useBannerDisconnectHandler()
|
||||
}
|
||||
)
|
||||
|
||||
if (private$withBS4) {
|
||||
# Attach boostrap 4 css shim
|
||||
if (getOption("shiny.minified", TRUE)) {
|
||||
css <- "bootstrap-4-shim.min.css"
|
||||
} else {
|
||||
css <- "bootstrap-4-shim.css"
|
||||
}
|
||||
uiDeps <- htmltools::htmlDependency(
|
||||
"AVSDevR.ShinyApplication",
|
||||
as.character(utils::packageVersion("AVSDevR.ShinyApplication")),
|
||||
c(file = system.file(package = "AVSDevR.ShinyApplication")),
|
||||
stylesheet = css
|
||||
)
|
||||
ui <- htmltools::attachDependencies(ui, uiDeps)
|
||||
}
|
||||
|
||||
# Set the language
|
||||
shiny:::setLang(ui, private$language)
|
||||
},
|
||||
server = function(input, output, session, ...) {
|
||||
if (!is.null(private$sessionLogger)) {
|
||||
private$sessionLogger$attachSession(session)
|
||||
}
|
||||
|
||||
shiny::callModule(
|
||||
private$appPage$server,
|
||||
"application",
|
||||
db_client = self$getSessionDBClient(session),
|
||||
...
|
||||
)
|
||||
},
|
||||
app = function() {
|
||||
shiny::shinyApp(self$ui(), self$server)
|
||||
}
|
||||
),
|
||||
private = list(
|
||||
appPage = NULL,
|
||||
language = "en",
|
||||
sessionLogger = NULL,
|
||||
withBS4 = FALSE
|
||||
)
|
||||
)
|
||||
Reference in New Issue
Block a user