2 votes

Menu dynamique dans shinydashboard avec conditionalPanel

Contexte

J'essaie de développer une application, qui a un écran de connexion et affiche différents menus en fonction des droits de l'utilisateur.

Les droits d'utilisateur sont hiérarchisés, ce qui signifie qu'un Read + Write doit avoir les mêmes droits qu'un utilisateur Read plus quelques droits supplémentaires.

Je me demande maintenant comment créer ce menu dynamique. Je lis ce document sur les IU dynamiques et j'espérais pouvoir atteindre mon objectif uniquement avec l'utilisation de conditionalPanel appels.

Dans le code ci-dessous, vous voyez qu'il y a beaucoup de duplications. Et le pire de tout, c'est que je dois attribuer des noms uniques aux éléments suivants tabs même s'ils sont dans des panels différents (mutuellement exclusifs) ( a1 y a2 ) mais qui sont destinés à faire exactement la même chose.

Choses essayées jusqu'à présent

J'ai essayé de déplacer le conditionalPanel en sidebarMenu (et tabItems respectivement), mais j'obtiens alors une erreur, car le type de retour de la fonction conditionalPanel ne correspond pas au type attendu.

Résultat escompté

Enfin, je veux que la duplication du code soit minimale. C'est-à-dire que je veux définir l'interface utilisateur de Do A y Do B exactement une fois mais réutilisation Do A pour les deux utilisateurs.

Quelles sont les options qui s'offrent à moi ? Dois-je me rabattre sur le rendu dynamique ( renderUI / renderMenu ) ou existe-t-il un moyen d'obtenir le comportement souhaité ? conditionalPanel seulement ?

Code de travail avec duplication

library(shiny)
library(shinydashboard)

ui <- dashboardPage(
   dashboardHeader(),
   dashboardSidebar(
      selectInput("userrights", label = "User Rights:", 
                   choices = c("Read + Write", "Read")),
      conditionalPanel("input.userrights == 'Read'",
                       sidebarMenu(
                          menuItem("Do A", tabName = "a1")
                       )
      ),
      conditionalPanel("input.userrights == 'Read + Write'",
                       sidebarMenu(
                          ## unnecessary duplication + I need yet another tab 'a2'
                          menuItem("Do A", tabName = "a2"),
                          menuItem("Do B", tabName = "b2")
                       )
      )
   ),
   dashboardBody(
      conditionalPanel("input.userrights == 'Read'",
                       tabItems(
                          tabItem("a1", h1("A was done"))
                       )
      ),
      conditionalPanel("input.userrights == 'Read + Write'",
                       tabItems(
                          tabItem("a2", h1("A was done")),
                          tabItem("b2", h1("B was done"))
                       )
      )
   )
)

server <- function(input, output) {}

runApp(shinyApp(ui, server))

Bribe : Ne fonctionne pas mais au moins sans duplication

sidebarMenu(
   menuItem("Do A", tabName = "a")
   conditionalPanel("input.userrights == 'Read + Write'",
      menuItem("Do B", tabName = "b")
   )
)

1voto

Florian Points 17872

Vous pouvez rendre votre menu dans le serveur en fonction de la saisie de l'utilisateur ou d'autres conditions, et le transmettre à l'interface utilisateur. Exemple de travail ci-dessous :

library(shiny)
library(shinydashboard)

ui <- dashboardPage(
  dashboardHeader(),
  dashboardSidebar(
    selectInput("userrights", label = "User Rights:", 
                choices = c("Read + Write", "Read")),
    sidebarMenuOutput("menu")
  ),
  dashboardBody(
    tabItems(
      tabItem("a", h1("A was done")),
      tabItem("b", h1("B was done"))
    )
  )
)

server <- function(input, output) {

  output$menu <- renderMenu({

    my_list = list(menuItem("a", tabName="a"))

    if(input$userrights=="Read + Write")
       my_list[[2]] = menuItem("b", tabName="b")

    sidebarMenu(my_list)

  })

}

runApp(shinyApp(ui, server))

J'espère que cela vous aidera !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X