如何为Shiny Dashboard添加登录页并隐藏侧边栏、tabPanel等组件
解决方案
需引入shinyjs包实现组件的动态显隐,核心修改逻辑为:默认隐藏所有业务组件仅保留登录页,登录验证通过后再触发显示侧边栏、控制栏、标签页等内容,完整修改后的代码如下:
library(shiny) library(shinydashboard) library(shinydashboardPlus) library(DT) library(shinyauthr) library(shinyjs) # 新增依赖 menu <- controlbarMenu( id = "controlbarMenu", controlbarItem( "Tab 1", "Welcome to tab 1" ), controlbarItem( "Tab 2", numericInput("num", "Observations:", 200, min = 1, max = 1000, step = 100) ) ) # 用户名密码配置 user_base <- tibble::tibble( user = c("user1", "user2"), password = sapply(c("pass1", "pass2"), sodium::password_store), permissions = c("admin", "standard"), name = c("User One", "User Two") ) shinyApp( ui = tags$body(class="skin-blue sidebar-mini", # 移除默认展开控制栏的class dashboardPage( options = list(sidebarExpandOnHover = TRUE), header = dashboardHeader(title = "Investment Advisor Monitoring - Insider Trading",titleWidth = 450), # 侧边栏默认设为折叠,所有内容改为动态渲染 sidebar = dashboardSidebar(minified = F, collapsed = T, uiOutput("sidebar_content") ), body = dashboardBody( useShinyjs(), # 启用shinyjs # 登录UI默认一直显示,登录后自动隐藏 shinyauthr::loginUI(id = "login"), # 所有登录后才显示的内容全部包在条件面板里 conditionalPanel( condition = "output.user_auth == true", div(class = "pull-right", shinyauthr::logoutUI(id = "logout")), h3('Results'), tabsetPanel(id = "tabs", tabPanel("InsiderTraining", box( title = " Table", status = "primary", solidHeader = TRUE, collapsible = TRUE,width = 12, dataTableOutput("Input"))), tabPanel("Tax Loss Harvesting", box( title = " Table", status = "primary", solidHeader = TRUE, collapsible = TRUE,width = 12, dataTableOutput("Input2"))) ) ) ), # 控制栏默认折叠,内容全部改为动态渲染 controlbar = dashboardControlbar(width = 300, collapsed = T, uiOutput("controlbar_content") ), title = "DashboardPage" )), server = function(input, output, session) { credentials <- shinyauthr::loginServer( id = "login", data = user_base, user_col = user, pwd_col = password, sodium_hashed = TRUE, log_out = reactive(logout_init()) ) logout_init <- shinyauthr::logoutServer( id = "logout", active = reactive(credentials()$user_auth) ) # 暴露登录状态给前端条件面板 output$user_auth <- reactive({ credentials()$user_auth }) outputOptions(output, "user_auth", suspendWhenHidden = FALSE) # 监听登录状态,动态控制组件显隐 observeEvent(credentials()$user_auth, { if(credentials()$user_auth){ # 登录成功:展开侧边栏和控制栏 updateDashboardSidebar(id = NULL, session = session, expanded = TRUE) updateControlbar(id = NULL, session = session, expanded = TRUE) }else{ # 退出登录:折叠侧边栏和控制栏 updateDashboardSidebar(id = NULL, session = session, expanded = FALSE) updateControlbar(id = NULL, session = session, expanded = FALSE) } }) # 侧边栏内容动态渲染 output$sidebar_content <- renderUI({ req(credentials()$user_auth) tagList( h4("Investment Selected"), uiOutput("mytab11"), uiOutput("mytab12") ) }) # 控制栏内容动态渲染 output$controlbar_content <- renderUI({ req(credentials()$user_auth) tagList( h4("Insider Trading Parameters"), uiOutput("mytab21"), uiOutput("mytab22"), uiOutput("mytab32") ) }) # 原有业务逻辑不变 output$Input<-renderDataTable({ req(credentials()$user_auth) datatable(mtcars) }) output$Input2<-renderDataTable({ req(credentials()$user_auth) datatable(mtcars) # 原代码mtcars2不存在,测试可替换为对应业务数据集 }) output$mytab11 <- renderUI({ req(credentials()$user_auth) tagList( conditionalPanel(condition = 'input.tabs=="InsiderTraining"', textInput("StockTicker", "Enter Stock Symbol", value = "NFLX"), )) }) output$mytab21 <- renderUI({ req(credentials()$user_auth) tagList( conditionalPanel(condition = 'input.tabs=="InsiderTraining"', selectInput("InsiderTradingModel", "Insider Trading Model", c("Dynamic" = "Dynamic", "AI based" = "AIbased")) )) }) output$mytab22 <- renderUI({ req(credentials()$user_auth) tagList( conditionalPanel(condition = 'input.tabs=="Switching"', selectInput("InsiderTradingModel2", "Insider Trading Model 2", c("Dynamic" = "Dynamic", "BI based" = "BIbased")) )) }) output$mytab32 <- renderUI({ req(credentials()$user_auth) tagList( conditionalPanel(condition = 'input.tabs=="Tax Loss Harvesting"', menu )) }) } )
内容的提问来源于stack exchange,提问作者firmo23
相关产品推荐
相关产品推荐

