Skip to content

Commit

Permalink
Shiny template module (#5)
Browse files Browse the repository at this point in the history
* New helper function to add css to UI

* Removed shiny-template cookie logic and replaced with dfeshiny cookie functions. Added cookie page to app. Removed use_shinydashboard.

* renv updated
  • Loading branch information
JT-39 authored Aug 22, 2024
1 parent 15e9185 commit 2269131
Show file tree
Hide file tree
Showing 5 changed files with 238 additions and 287 deletions.
184 changes: 110 additions & 74 deletions R/helper_functions.R
Original file line number Diff line number Diff line change
@@ -1,74 +1,110 @@
# -----------------------------------------------------------------------------
# This is the helper file, filled with lots of helpful functions!
#
# It is commonly used as an R script to store custom functions used through the
# app to keep the rest of the app code easier to read.
# -----------------------------------------------------------------------------

# Expandable function ---------------------------------------------------------
expandable <- function(input_id, label, contents) {
gov_details <- shiny::tags$details(
class = "govuk-details", id = input_id,
shiny::tags$summary(
class = "govuk-details__summary",
shiny::tags$span(
class = "govuk-details__summary-text",
label
)
),
shiny::tags$div(contents)
)
}

# Value box function ----------------------------------------------------------
# fontsize: can be small, medium or large
value_box <- function(value, subtitle, icon = NULL,
color = "blue", width = 4,
href = NULL, fontsize = "medium") {
validate_color(color)
if (!is.null(icon)) tagAssert(icon, type = "i")

box_content <- div(
class = paste0("small-box bg-", color),
div(
class = "inner",
p(value, id = paste0("vboxhead-", fontsize)),
p(subtitle, id = paste0("vboxdetail-", fontsize))
),
if (!is.null(icon)) div(class = "icon-large", icon)
)

if (!is.null(href)) {
box_content <- a(href = href, box_content)
}

div(
class = if (!is.null(width)) paste0("col-sm-", width),
box_content
)
}

# Valid colours for value box -------------------------------------------------
valid_colors <- c("blue", "dark-blue", "green", "orange", "purple", "white")

# Validate that only valid colours are used -----------------------------------
validate_color <- function(color) {
if (color %in% valid_colors) {
return(TRUE)
}

stop(
"Invalid color: ", color, ". Valid colors are: ",
paste(valid_colors, collapse = ", "), "."
)
}

# GSS colours -----------------------------------------------------------------
# Current GSS colours for use in charts. These are taken from the current
# guidance here:
# https://analysisfunction.civilservice.gov.uk/policy-store/data-visualisation-colours-in-charts/
# Note the advice on trying to keep to a maximum of 4 series in a single plot
# AF colours package guidance here: https://best-practice-and-impact.github.io/afcolours/
suppressMessages(
gss_colour_pallette <- afcolours::af_colours("categorical", colour_format = "hex", n = 4)
)
# -----------------------------------------------------------------------------
# This is the helper file, filled with lots of helpful functions!
#
# It is commonly used as an R script to store custom functions used through the
# app to keep the rest of the app code easier to read.
# -----------------------------------------------------------------------------

# Expandable function ---------------------------------------------------------
expandable <- function(input_id, label, contents) {
gov_details <- shiny::tags$details(
class = "govuk-details", id = input_id,
shiny::tags$summary(
class = "govuk-details__summary",
shiny::tags$span(
class = "govuk-details__summary-text",
label
)
),
shiny::tags$div(contents)
)
}

# Value box function ----------------------------------------------------------
# fontsize: can be small, medium or large
value_box <- function(value, subtitle, icon = NULL,
color = "blue", width = 4,
href = NULL, fontsize = "medium") {
validate_color(color)
if (!is.null(icon)) tagAssert(icon, type = "i")

box_content <- div(
class = paste0("small-box bg-", color),
div(
class = "inner",
p(value, id = paste0("vboxhead-", fontsize)),
p(subtitle, id = paste0("vboxdetail-", fontsize))
),
if (!is.null(icon)) div(class = "icon-large", icon)
)

if (!is.null(href)) {
box_content <- a(href = href, box_content)
}

div(
class = if (!is.null(width)) paste0("col-sm-", width),
box_content
)
}

# Valid colours for value box -------------------------------------------------
valid_colors <- c("blue", "dark-blue", "green", "orange", "purple", "white")

# Validate that only valid colours are used -----------------------------------
validate_color <- function(color) {
if (color %in% valid_colors) {
return(TRUE)
}

stop(
"Invalid color: ", color, ". Valid colors are: ",
paste(valid_colors, collapse = ", "), "."
)
}

# GSS colours -----------------------------------------------------------------
# Current GSS colours for use in charts. These are taken from the current
# guidance here:
# https://analysisfunction.civilservice.gov.uk/policy-store/data-visualisation-colours-in-charts/
# Note the advice on trying to keep to a maximum of 4 series in a single plot
# AF colours package guidance here: https://best-practice-and-impact.github.io/afcolours/
suppressMessages(
gss_colour_pallette <- afcolours::af_colours("categorical", colour_format = "hex", n = 4)
)


#' Set CSS Style Sheet --------------------------------------------------------
#'
#' This function generates an HTML `head` tag that includes a
#' link to a specified CSS stylesheet.
#' It can be used to dynamically set or include a CSS file in a Shiny
#' application or any other HTML-based interface that utilizes R.
#'
#' @param css_filename A character string specifying the path or
#' URL to the CSS file.
#' This should be a relative or absolute path to a `.css` file or a URL
#' pointing to an external stylesheet.
#'
#' @return A `tags$head` object containing a `link` tag that references
#' the specified CSS file.
#' This object can be directly included in the UI definition of a
#' Shiny application.
#'
#' @details
#' When included in the UI of a Shiny app, it instructs the web browser
#' to load and apply the specified CSS stylesheet.
#'
#' This function is useful when you need to modularise the
#' inclusion of stylesheets, especially in applications where the CSS file
#' might change dynamically or needs to be set programmatically.
#'
set_css_style_sheet <- function(css_filename) {
tags$head(
tags$link(
rel = "stylesheet",
type = "text/css",
href = css_filename
)
)
}
1 change: 1 addition & 0 deletions global.R
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ source(here::here("R/helper_functions.R"))

# Source all files in the ui_panels folder
lapply(list.files(here::here("R/ui_panels/"), full.names = TRUE), source)
lapply(list.files(here::here("R/general_modules/"), full.names = TRUE), source)

# Set global variables --------------------------------------------------------

Expand Down
2 changes: 1 addition & 1 deletion renv.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1306,7 +1306,7 @@
"Package": "shinyWidgets",
"Version": "0.8.6",
"Source": "Repository",
"Repository": "RSPM",
"Repository": "CRAN",
"Requirements": [
"R",
"anytime",
Expand Down
103 changes: 12 additions & 91 deletions server.R
Original file line number Diff line number Diff line change
Expand Up @@ -68,99 +68,20 @@ server <- function(input, output, session) {
# })

# Cookies logic -------------------------------------------------------------
shiny::observeEvent(input$cookies, {
if (!is.null(input$cookies)) {
if (!("dfe_analytics" %in% names(input$cookies))) {
shinyjs::show(id = "cookieMain")
} else {
shinyjs::hide(id = "cookieMain")
msg <- list(
name = "dfe_analytics",
value = input$cookies$dfe_analytics
)
session$sendCustomMessage("analytics-consent", msg)
if ("cookies" %in% names(input)) {
if ("dfe_analytics" %in% names(input$cookies)) {
if (input$cookies$dfe_analytics == "denied") {
ga_msg <- list(name = paste0("_ga_", google_analytics_key))
session$sendCustomMessage("cookie-remove", ga_msg)
}
}
}
}
} else {
shinyjs::hide(id = "cookieMain")
}
})

# Need these set of observeEvent to create a path through the cookie banner
shiny::observeEvent(input$cookieAccept, {
msg <- list(
name = "dfe_analytics",
value = "granted"
)
session$sendCustomMessage("cookie-set", msg)
session$sendCustomMessage("analytics-consent", msg)
shinyjs::show(id = "cookieAcceptDiv")
shinyjs::hide(id = "cookieMain")
})

shiny::observeEvent(input$cookieReject, {
msg <- list(
name = "dfe_analytics",
value = "denied"
)
session$sendCustomMessage("cookie-set", msg)
session$sendCustomMessage("analytics-consent", msg)
shinyjs::show(id = "cookieRejectDiv")
shinyjs::hide(id = "cookieMain")
})

shiny::observeEvent(input$hideAccept, {
shinyjs::toggle(id = "cookieDiv")
})

shiny::observeEvent(input$hideReject, {
shinyjs::toggle(id = "cookieDiv")
})

shiny::observeEvent(input$remove, {
shinyjs::toggle(id = "cookieMain")
msg <- list(name = "dfe_analytics", value = "denied")
session$sendCustomMessage("cookie-remove", msg)
session$sendCustomMessage("analytics-consent", msg)
print(input$cookies)
})

cookies_data <- shiny::reactive({
input$cookies
})
output$cookie_status <- dfeshiny::cookie_banner_server(
"cookie-banner",
input_cookies = shiny::reactive(input$cookies),
parent_session = session,
google_analytics_key = google_analytics_key,
cookie_link_panel = "cookies_panel_ui"
)

output$cookie_status <- shiny::renderText({
cookie_text_stem <- "To better understand the reach of our dashboard tools,
this site uses cookies to identify numbers of unique users as part of Google
Analytics. You have chosen to"
cookie_text_tail <- "the use of cookies on this website."
if ("cookies" %in% names(input)) {
if ("dfe_analytics" %in% names(input$cookies)) {
if (input$cookies$dfe_analytics == "granted") {
paste(cookie_text_stem, "accept", cookie_text_tail)
} else {
paste(cookie_text_stem, "reject", cookie_text_tail)
}
}
} else {
"Cookies consent has not been confirmed."
}
})
dfeshiny::cookies_panel_server(
id = "cookie-panel",
input_cookies = shiny::reactive(input$cookies),
google_analytics_key = google_analytics_key
)

shiny::observeEvent(input$cookieLink, {
# Need to link here to where further info is located. You can
# updateTabsetPanel to have a cookie page for instance
shiny::updateTabsetPanel(session, "navlistPanel",
selected = "Support and feedback"
)
})

# Dataset with timeseries data ----------------------------------------------
reactive_rev_bal <- shiny::reactive({
Expand Down
Loading

0 comments on commit 2269131

Please sign in to comment.