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

Dynamic UI #41

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,5 @@ importFrom(shinyWidgets,virtualSelectInput)
importFrom(shinycssloaders,withSpinner)
importFrom(shinyjs,onclick)
importFrom(shinyjs,useShinyjs)
importFrom(stringr,str_replace_all)
importFrom(stringr,str_split)
67 changes: 59 additions & 8 deletions R/app_server.R
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,72 @@
#' @noRd
app_server <- function(input, output, session) {

# Show welcome modal
showModal(modalDialog(
title = "Important message",
HTML("Welcome to the development version of the fisheriesXplorer application. <u>The contents are indicative and should not be quoted or used elsewhere</u>.")
))

# Extract current date information
app_date <- str_split(date(), pattern = " ")[[1]]
cap_year <- app_date[5]
cap_month <- app_date[2]

# Reactive value to store selected ecoregion
selected_ecoregion <- reactiveVal(NULL)

mod_navigation_page_server("navigation_page_1", parent_session = session)
mod_overview_server("overview_1")
mod_landings_server("landings_1", cap_year, cap_month)
mod_stock_status_server("stock_status_1", cap_year, cap_month)
mod_mixfish_server("mixfish_1")
mod_vms_server("vms_1")
mod_bycatch_server("bycatch_1")
}

# Initialize Modules
mod_navigation_page_server("navigation_page_1", parent_session = session, selected_ecoregion = selected_ecoregion)
mod_overview_server("overview_1", selected_ecoregion)
mod_landings_server("landings_1", cap_year, cap_month, selected_ecoregion)
mod_stock_status_server("stock_status_1", cap_year, cap_month, selected_ecoregion)
mod_mixfish_server("mixfish_1", selected_ecoregion)
mod_vms_server("vms_1", selected_ecoregion)
mod_bycatch_server("bycatch_1", selected_ecoregion)

# Observer to manage dynamic navbar tabs
observeEvent(selected_ecoregion(), {
req(selected_ecoregion())

# Define all possible dynamic tabs
all_tabs <- c("Overview", "Landings", "Stock Status", "Mixed Fisheries", "VMS", "Bycatch")

# Remove existing dynamic tabs if any
lapply(all_tabs, function(tab_name) {
removeTab(inputId = "main-navbar", target = tab_name)
})

# Fetch the configuration for the selected ecoregion
ecoregion_config <- config$ecoregions[[selected_ecoregion()]]$tabs
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: Potential for runtime errors if configuration structure is incorrect.

The dynamic tab generation relies heavily on the structure of the configuration file. Consider implementing error checking to gracefully handle cases where the configuration doesn't match the expected structure, to prevent runtime errors.


if (!is.null(ecoregion_config)) {
# Iterate through each tab in the config and insert it
for (tab_key in names(ecoregion_config)) {
tab_name <- tools::toTitleCase(gsub("_", " ", tab_key))

# Ensure tab_name is in the list of all_tabs
if (tab_name %in% all_tabs) {
# Generate the UI using the corresponding module
tab_ui <- switch(tab_key,
"overview" = mod_overview_ui("overview_1", ecoregion_config[[tab_key]]$sub_tabs),
"landings" = mod_landings_ui("landings_1", ecoregion_config[[tab_key]]$sub_tabs),
"stock_status" = mod_stock_status_ui("stock_status_1", ecoregion_config[[tab_key]]$sub_tabs),
"mixed_fisheries" = mod_mixfish_ui("mixfish_1"),
"vms" = mod_vms_ui("vms_1", ecoregion_config[[tab_key]]$sub_tabs),
"bycatch" = mod_bycatch_ui("bycatch_1", ecoregion_config[[tab_key]]$sub_tabs)
)

if (!is.null(tab_ui)) {
# Insert the tab after the "Home" tab
appendTab(
inputId = "main-navbar",
tab = tabPanel(tab_name, tab_ui),
select = FALSE
)
}
}
}
}
}, ignoreNULL = FALSE)
}
65 changes: 23 additions & 42 deletions R/app_ui.R
Original file line number Diff line number Diff line change
Expand Up @@ -6,53 +6,28 @@
#' @importFrom desc desc_get_version
#' @noRd
app_ui <- function(request) {
title_html <- tags$a(
href = "https://ices-tools-dev.shinyapps.io/fisheriesXplorer/",
tags$img(
src = "www/negative_ices_logo.png",
style = "margin-top: -15px; margin-bottom: 0px; padding-right:10px;",
height = "50px"
)
)

tagList(
# Leave this function for adding external resources
golem_add_external_resources(),
title_html <- tags$a(
href = "https://ices-tools-dev.shinyapps.io/fisheriesXplorer/",
tags$img(
src = "www/negative_ices_logo.png",
style = "margin-top: -15px; margin-bottom: 0px; padding-right:10px;",
height = "50px"
)
options(
spinner.type = 5,
spinner.color = "#00B6F1",
spinner.size = 0.7
),
options(spinner.type = 5,
spinner.color = "#00B6F1",
spinner.size = 0.7),

navbarPage(
title = title_html,
position = "static-top",
collapsible = TRUE,
fluid = TRUE,
windowTitle = "fisheriesXplorer",
id = "nav-page",
tabPanel("Home",
id = "home",
mod_navigation_page_ui("navigation_page_1")
),
tabPanel(
"Overview",
mod_overview_ui("overview_1")
),
id = "main-navbar",
tabPanel(
"Landings",
mod_landings_ui("landings_1")
),
tabPanel(
"Stock Status",
mod_stock_status_ui("stock_status_1")
),
tabPanel("Mixed Fisheries",
mod_mixfish_ui("mixfish_1")),
tabPanel(
"VMS",
mod_vms_ui("vms_1")
),
tabPanel(
"Bycatch",
mod_bycatch_ui("bycatch_1")
"Home",
mod_navigation_page_ui("navigation_page_1")
)
)
)
Expand Down Expand Up @@ -92,7 +67,13 @@ golem_add_external_resources <- function() {
tags$head(tags$link(rel = "stylesheet", type = "text/css", href = "styles.css")),

# Add here other external resources
useShinyjs()
useShinyjs(),

tags$script("
Shiny.addCustomMessageHandler('triggerNavbarRender', function(message) {
Shiny.setInputValue('triggerNavbarRender', Math.random());
});
")

)
}
3 changes: 3 additions & 0 deletions R/global.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# In global.R or at the top of app_server.R
library(yaml)
config <- yaml::read_yaml("inst/tab-config.yml")
4 changes: 2 additions & 2 deletions R/mod_bycatch.R
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#' @noRd
#'
#' @importFrom shiny NS tagList
mod_bycatch_ui <- function(id) {
mod_bycatch_ui <- function(id, sub_tabs) {
ns <- NS(id)
tagList(
layout_sidebar(bg = "white", fg = "black",
Expand All @@ -33,7 +33,7 @@ mod_bycatch_ui <- function(id) {
#' bycatch Server Functions
#'
#' @noRd
mod_bycatch_server <- function(id){
mod_bycatch_server <- function(id, selected_ecoregion){
moduleServer( id, function(input, output, session){
ns <- session$ns

Expand Down
4 changes: 2 additions & 2 deletions R/mod_landings.R
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#' @importFrom plotly ggplotly plotlyOutput renderPlotly
#' @importFrom shinycssloaders withSpinner

mod_landings_ui <- function(id) {
mod_landings_ui <- function(id, sub_tabs) {
ns <- NS(id)
tagList(
tabsetPanel(
Expand Down Expand Up @@ -62,7 +62,7 @@ mod_landings_ui <- function(id) {
#' landings Server Functions
#'
#' @noRd
mod_landings_server <- function(id, cap_year, cap_month){
mod_landings_server <- function(id, cap_year, cap_month, selected_ecoregion){
moduleServer( id, function(input, output, session){
ns <- session$ns

Expand Down
4 changes: 2 additions & 2 deletions R/mod_mixfish.R
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#' @importFrom shiny NS tagList
#' @importFrom mixfishtools plot_catchScenStk
#' @importFrom datamods select_group_server select_group_ui
mod_mixfish_ui <- function(id){
mod_mixfish_ui <- function(id, sub_tabs){
ns <- NS(id)
tagList(
navset_tab(
Expand Down Expand Up @@ -38,7 +38,7 @@ mod_mixfish_ui <- function(id){
#' mixfish Server Functions
#'
#' @noRd
mod_mixfish_server <- function(id){
mod_mixfish_server <- function(id, selected_ecoregion){
moduleServer( id, function(input, output, session){
ns <- session$ns

Expand Down
79 changes: 46 additions & 33 deletions R/mod_navigation_page.R
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#' landing_page UI Function
#' navigation_page UI Function
#'
#' @description A shiny Module.
#'
Expand All @@ -7,11 +7,12 @@
#' @noRd
#'
#' @importFrom shiny NS tagList
#' @importFrom bslib card card_header card_body layout_column_wrap nav_panel layout_sidebar sidebar
#' @importFrom bslib card card_header card_body layout_column_wrap
#' @importFrom leaflet leafletOutput leafletProxy hideGroup showGroup
#' @importFrom shinyWidgets virtualSelectInput updateVirtualSelect
#' @importFrom shinyjs onclick
mod_navigation_page_ui <- function(id) {
#' @importFrom stringr str_replace_all
mod_navigation_page_ui <- function(id, sub_tabs) {
ns <- NS(id)
tagList(
tags$img(id = "logo", class = "center-block", src = "www/fisheriesxplorer_blue.png"),
Expand All @@ -37,7 +38,7 @@ mod_navigation_page_ui <- function(id) {
inputId = ns("selected_locations"),
label = "Selected ICES Ecoregion:",
choices = sort(eco_shape$Ecoregion),
selected = "Greater North Sea",
selected = NULL,
multiple = FALSE,
width = "100%",
search = TRUE,
Expand Down Expand Up @@ -114,70 +115,82 @@ mod_navigation_page_ui <- function(id) {
)
}

#' landing_page Server Functions
#' navigation_page Server Functions
#'
#' @noRd
mod_navigation_page_server <- function(id, parent_session) {
mod_navigation_page_server <- function(id, parent_session, selected_ecoregion) {
moduleServer(id, function(input, output, session) {
ns <- session$ns

output$map <- leaflet::renderLeaflet({
print("Rendering map")
print(paste("eco_shape dimensions:", nrow(eco_shape), "x", ncol(eco_shape)))
print(paste("map_shape dimensions:", nrow(map_shape), "x", ncol(map_shape)))
map_ecoregion(eco_shape, map_shape)
})
proxy_map <- leafletProxy("map")

# create empty character vector to hold map selected locations
# Create empty character vector to hold map selected locations
selected_map <- reactiveValues(groups = character())

observeEvent(input$map_shape_click, {
req(!is.null(input$map_shape_click$id))

if (input$map_shape_click$group == "Eco_regions") {
selected_map$groups <- c(selected_map$groups, input$map_shape_click$id)
}

updateVirtualSelect(
inputId = "selected_locations",
choices = eco_shape$Ecoregion,
selected = input$map_shape_click$id
)
})

observeEvent(input$selected_locations,
{
removed <- setdiff(selected_map$groups, input$selected_locations)
selected_map$groups <- input$selected_locations

proxy_map %>%
hideGroup(removed) %>%
showGroup(input$selected_locations)
},
ignoreNULL = FALSE
)
}, ignoreNULL = TRUE, ignoreInit = TRUE)

observeEvent(input$selected_locations, {
req(input$selected_locations)

temp_location <- input$selected_locations
temp_location <- str_replace_all(temp_location, " ", "_")
temp_location <- tolower(temp_location)

selected_ecoregion(temp_location)

# Optional: Remove if not needed anymore
# session$sendCustomMessage("triggerNavbarRender", list())

removed <- setdiff(selected_map$groups, input$selected_locations)
selected_map$groups <- input$selected_locations

proxy_map %>%
hideGroup(removed) %>%
showGroup(input$selected_locations)
}, ignoreNULL = TRUE, ignoreInit = TRUE)

# Update buttons to navigate tabs
onclick("overviewBtn", expr = {
updateNavbarPage(session = parent_session, "nav-page", selected = "Overview")
updateNavbarPage(session = parent_session, inputId = "main-navbar", selected = "Overview")
})
onclick("landingsBtn", expr = {
updateNavbarPage(session = parent_session, "nav-page", selected = "Landings")
updateNavbarPage(session = parent_session, inputId = "main-navbar", selected = "Landings")
})
onclick("stockStatusBtn", expr = {
updateNavbarPage(session = parent_session, "nav-page", selected = "Stock Status")
updateNavbarPage(session = parent_session, inputId = "main-navbar", selected = "Stock Status")
})
onclick("mixfishBtn", expr = {
updateNavbarPage(session = parent_session, "nav-page", selected = "Mixed Fisheries")
updateNavbarPage(session = parent_session, inputId = "main-navbar", selected = "Mixed Fisheries")
})
onclick("VMS", expr = {
updateNavbarPage(session = parent_session, "nav-page", selected = "VMS")
updateNavbarPage(session = parent_session, inputId = "main-navbar", selected = "VMS")
})
onclick("bycatchBtn", expr = {
updateNavbarPage(session = parent_session, "nav-page", selected = "Bycatch")
updateNavbarPage(session = parent_session, inputId = "main-navbar", selected = "Bycatch")
})
})
}

## To be copied in the UI
# mod_navigation_page_ui("navigation_page_1")

## To be copied in the server
# mod_navigation_page_server("navigation_page_1")
# mod_navigation_page_server("navigation_page_1")
4 changes: 2 additions & 2 deletions R/mod_overview.R
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#' @noRd
#'
#' @importFrom shiny NS tagList
mod_overview_ui <- function(id) {
mod_overview_ui <- function(id, sub_tabs) {
ns <- NS(id)
tagList(
tabsetPanel(
Expand Down Expand Up @@ -42,7 +42,7 @@ mod_overview_ui <- function(id) {
#' overview Server Functions
#'
#' @noRd
mod_overview_server <- function(id){
mod_overview_server <- function(id, selected_ecoregion){
moduleServer( id, function(input, output, session){
ns <- session$ns

Expand Down
Loading