periscope2 is a scalable and UI-standardized ‘shiny’ framework including a variety of developer convenience functions with the goal of both streamlining robust application development and assisting in creating a consistent user experience regardless of application or developer.
periscope2 is rich of developer-friendly features as:
periscope2 layout depends on bs4Dash layout as each application can have up to 5 different sections.
1: Left Sidebar
The left sidebar is largely intended for configuration options, settings, and general user application controls and functionality that will affect the body of the application.
Left sidebar supports any shiny UI element. In a multi-page app there can also be menu items in which each item can be linked to a separate body page.
The left sidebar can be collapsed in desktop mode to maximize the user’s view of the application body when they do not immediately need the configuration options and settings. Also, it is possible to create an application without a left sidebar.
2: Header
periscope2 uses the header to display the application title and any additional application information.
It is also used for displaying session busy indicator and announcements alerts.
Header can also be used to hold custom menu items to link to other apps, pages or any custom functions.
3: Right Sidebar
The right sidebar is, like the left sidebar, largely intended for configuration options, settings, and general user application controls and functionality that will affect the body of the application.
The right sidebar is optional. When used it is collapsed by default and can be opened by clicking on the icon (which can be customized).
4: Footer
The footer supports short textual or html formatted info/citations.
5: Body
This is the main body area for applications where charts and figures, tables, etc. are placed by the application developer. If desired the developer can add multiple pages or views and switch among them from menu options in the left sidebar, right sidebar or header sections.
sample_app
parameter in create_application
to TRUE
FALSE
?create_application
for more detailsThe application layout will adapt to user device size automatically by re-flowing the content.
This indicator shows in the header bar automatically when the shiny application is busy. There is no code or configuration necessary to tie in this functionality.
The framework makes it easy to log user actions. Framework user interactions are automatically logged. Recorded logs can be viewed automatically using logViewer module
# Add a user action to the log
loginfo("Your Information Message with %s, %s parameters", parm1, parm2, logger = ss_userAction.Log)
# Add a warning to the log
logwarn("Your Warning Message!", logger = ss_userAction.Log)
Examples of app log in console:
There are five standardized locations for user-alerts:
All alerts can be dismissed by the user and are colored by setting the status.
Alerts can accumulate (i.e. append to each other) or replace previous alerts.
createPSAlert(id = 'bodyAlert',
options = list(title = 'alert title',
status = 'warning',
closable = TRUE,
content = alert contents))
# id is the location of the alert and can be one of:
# 'sidebarRightAlert', 'sidebarBasicAlert', 'bodyAlert', 'footerAlert' and 'headerAlert'
# status sets the bootstrap styling and can be one of:
# 'primary', 'success', 'warning', 'danger' or 'info'
An indicator that displayed upon application start up or reload and it can be customized in ‘program/global.R’
This is a highly-functional set of custom-styled buttons with the built-in ability to download data in different file formats
See the downloadFileButton Vignette for more detailed information
This is a highly-functional custom styled table that includes a downloadFileButton linked to the data
See the downloadableTable Vignette for more detailed information
This is a custom plot output that is paired with a linked downloadFile button that allows the user to download the plot (and optionally data) in different file formats
See the downloadablePlot Vignette for more detailed information
This adds the ability to alert the app’s users with customized messages at the top of the application on startup. This is configurable using the ‘program/config/announce.yaml’ file.
See the Announcement Vignette for more detailed information
Resets a user’s session and rolls over their log
See the Application Reset Vignette for more detailed information
View application session recorded log
See the Log Viewer Vignette for more detailed information
library(periscope2)
app_dir = tempdir()
# application without a right sidebar
create_application(name = 'mytestapp',
location = app_dir,
sample_app = TRUE)
# application without a left sidebar or a right sidebar
create_application(name = 'mytestapp',
location = app_dir,
sample_app = TRUE,
left_sidebar = FALSE)
# application with left and right sidebars
create_application(name = 'mytestapp',
location = app_dir,
sample_app = TRUE,
right_sidebar = TRUE)
This generates a default sample application optionally with a left/right sidebar in a subdirectory named mytestapp at the specified location. The location must exist when calling this function.
Note: If the mytestapp directory in this location already exists it will not be overwritten - the function will give a warning and exit without modifying the user’s system.
The application will run in either the viewer or browser (depending on system preferences/settings). It will contain help text, test buttons, a sample log, etc. You can use this sample application to explore the functionality and code.
library(periscope2)
app_dir = tempdir()
# application without a right sidebar
create_application(name = 'mytestapp',
location = app_dir)
# application without a left sidebar or a right sidebar
create_application(name = 'mytestapp',
location = app_dir,
left_sidebar = FALSE)
# application with a right sidebar
create_application(name = 'mytestapp',
location = app_dir,
right_sidebar = TRUE)
This generates a default blank application optionally with a left/right sidebar in a subdirectory named mytestapp at the specified location. The location must exist when calling this function.
Note: If the mytestapp directory in this location already exists it will not be overwritten - the function will give a warning and exit without modifying the directory.
It is recommended to run the empty application after creation to ensure a proper setup before beginning to customize the application.
All user customization is done in the files in the program subdirectory. We’ll walk through a few examples of how to add components and functionality as in a typical shiny application using this framework.
Set your application title, version, information, loading_indicator, announcements_file and change the logging level using set_app_parameters().
The app_version parameter in this function has a default value of “1.0.0”. It is recommended to follow the best practice in R’s packaging versioning. This means that a version consists of 3 numbers, <major>.<minor>.<patch>.
The titleinfo parameter in this function can be:
The announcements_file parameter points to the announcements module configuration file. Set this parameter to NULL to disable this feature
Important: Any variables or functions placed into this file are globally scoped and will be available across all user sessions.
# Plain text title
set_app_parameters(title = "My Application Title")
# Application Title links to an external url
set_app_parameters(title = "My Application Title",
titleinfo = "Application Valid Website")
# Application Title links to a modal window with HTML content
set_app_parameters(title = "My Application Title",
titleinfo = HTML("<h3>This is information about this application</h3>",
"<p><b>Author: </b>Me</p>",
"<p><b>Date: </b>", Sys.Date(), "</p>"))
# Application Title links to a modal window with HTML content, setting log level to 'DEBUG',
# using simple loading screen, init app version and pass announcements configuration module file
set_app_parameters(title = "periscope Example Application",
app_info = HTML("Demonstrate periscope features and generated application layout"),
log_level = "DEBUG",
app_version = "1.0.0",
loading_indicator = list(html = tagList(spin_1(), "Loading ...")),
announcements_file = "./program/config/announce.yaml")
Create UI components for the body and register them with the framework using a call to add_ui_body(). Use box elements for consistent presentation of your UI sections. Remember that different layout options and different box types configured in bs4Dash can be used.
body1 <- box(id = "bodyElement1",
title = "Box 1",
width = 8, #2/3 of the width (for 12 columns layout)
status = "primary", #colored bar at the top
collapsible = TRUE,
collapsed = FALSE,
htmlOutput("example1") )
body2 <- box(id = "bodyElement2",
title = "Box 2",
width = 4, #1/3 of the width (for 12 columns layout)
status = "danger", #colored bar at the top
collapsible = FALSE,
p("Some great text in paragraph format"),
pre("A pre-formatted (e.g. code) block"),
actionButton("exButton", label = "Example") )
add_ui_body(body_elements = list(body1, body2))
In the above example UI elements are being added in 2 different ways. body1 uses an htmlOutput element to set a placeholder for the id “example1” which will be setup in the server file. This is commonly used when there is need for a dynamic UI element that cannot be setup ahead of the session (for example it is dependent on data at runtime). body2 defines the UI elements in place here.
This illustrates the two most common paradigms for creating shiny UI elements. For more information on programming applications see the Shiny documentation.
Create UI elements for the application header and attach them to the UI by calling add_ui_header()
# Navbar skin. "dark" or "light"
skin <- "light"
# Navbar status
status <- "white"
# Whether to separate the navbar and body by a border.
border <- TRUE
# Whether items should be compacted
compact <- FALSE
# Icon of the main sidebar toggle
left_sidebar_icon <- shiny::icon("bars")
# Icon to toggle the controlbar
right_sidebar_icon <- shiny::icon("th")
add_ui_header(skin = skin,
status = status,
border = border,
compact = compact,
left_sidebar_icon = left_sidebar_icon,
right_sidebar_icon = right_sidebar_icon)
Create your application functionality in this file. This corresponds to the inside of the shinyServer(…) call in a traditional Shiny application and is where the majority of your application code will reside. The variables and functions in this file are isolated to a single application session.
Variables Available
You can also call the get_url_parameters(session) function to retrieve anything passed to the application session as URL parameters.
source("program/fxn/makeplot.R")
#build the deferred UI from ui_body.R
output$example1 <- renderUI({
list(downloadFileButton("ex_d1", c("csv"), "Download CSV"),
hr(),
p("Some great explanatory text in my application"))
})
downloadFile("ex_d1", ss_userAction.Log, "mydownload", list(csv=get_ref_data))
observeEvent(input$exButton, {
loginfo("exButton Pressed!", logger = ss_userAction.Log)
createPSAlert(
id = 'alert place',
options = list(title = 'alert title',
status = 'alert status'',
closable = TRUE,
content = "alert contents"))
})
Create variables and functions in this file that are available across all sessions and users of your application. It corresponds to the area above the shinyServer(…) call in a traditional Shiny application and generally there will not be a lot of usage of this file because of its global scoping. However, one of the common uses is to load reference data sets that are the same for all users of the application.
Use this directory to store data for your application. Note that a .gitignore file has been added so that data is not accidentally versioned. If you want to version files in this directory you will need to modify this file accordingly.
Use this directory to store configurations for your application (i.e. announcements configuration file)
Use this directory to store modules code for your application
Use this directory to store your .R files containing helper functions. Don’t forget to source these files in the appropriate place according to your scoping needs. (i.e. you would source a file in server_local.R to scope by user session, server_global.R to scope across all sessions, and global.R to scope across all sessions and UI)
Different parts of the generated application can be customized with this file values. The application must be restarted for changes to take effect.
Part of the file
Advanced css customization should go in this location
Advanced js customization should go in this location
Application images can be stored here
Vignettes