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

pivottable does not work with login/logout module #102

Open
AndreasPhilippi opened this issue Sep 18, 2019 · 7 comments
Open

pivottable does not work with login/logout module #102

AndreasPhilippi opened this issue Sep 18, 2019 · 7 comments

Comments

@AndreasPhilippi
Copy link

Hi, Im trying to use your package in my app but unfortunally it seems there is a bug.
First a short introduction in the problem and my app:
The app uses an login interface for authentification. If the user input was valid the ui changes from login to dashboard view. One part of the dashboar is the pivottable. Up to here everythinkg works fine but if I click on the logout button and login again, the pivottable does not show up anymore. I'm trying to fix that issue since days. First I thought that my code is not working properly but if I replace the pivottable with some other reactive output everthing is working fine. Only when I include the pivottable in the server all reactive outputs are no longer displayed.
The following code is just a snipped of my app.

Would be very grateful for help!

if (!require("pacman")) install.packages("pacman")
pacman::p_load(shiny, shinyBS, shinydashboard, shinyjs, dplyr,RMySQL,pool,rpivotTable)

#devtools::install_github(c("ramnathv/htmlwidgets", "smartinsightsfromdata/rpivotTable"))


mydata <- data.frame(
  product = c('A','B','C','A','B','C','A','B','C'),
  sold = c(5, 10, 15, 7, 6, 5, 9, 3, 1),
  date = as.Date(c('2010-01-01','2010-01-01','2010-01-01','2010-01-02','2010-01-02','2010-01-02','2010-01-03','2010-01-03','2010-01-03'))
)

user_data <- data.frame(
  user = c("Andreas", "Sascha", "Tobias"),
  password = c("123","123","123"), 
  permissions = c("admin","admin","admin"),
  name = c("Andreas", "Sascha", "Tobias"),
  stringsAsFactors = FALSE,
  row.names = NULL
)

ui <- dashboardPage(
  
  # Dashboardheader
  dashboardHeader(uiOutput("header")),
  
  # Dashboardsidebar
  dashboardSidebar(collapsed = TRUE,
                   sidebarMenu(id = "sidebar", sidebarMenuOutput("sidebar"))),
  
  # Dashboardbody
  dashboardBody(
    
    # Turn shinyjs on
    shinyjs::useShinyjs(),
    
    uiOutput("body")
  )
)

server <- function(input, output) {
  values <- reactiveValues()
  # reactive value to trigger the body, sidebar, header of dashboard depending on the login-state 
  values$login <- FALSE
  
  # header of login-Module (nothing in it)
  login_header <- function(){
  }
  
  # header if user is logged in
  auth_header <- function(){
    fluidRow(
      column(12,actionButton("logout_button","Logout",class = "btn-danger", style = "color: white; border-color: #d73925; background: #dd4b39")))
  }
  
  # Sidebar of login-Module (empty)
  login_sidebar <- function(){
    sidebarMenu()
  }
  
  # Sidebar if user is logged in 
  admin_sidebar <- function(){
    
    sidebarMenu(
      menuItem("Home", tabName = "home", icon = icon("home"))
    )
  }
  
  # Body if user is logged in 
  admin_body <- function(){
    tabItems(
      # Body for "Startseite" menuItem  
      tabItem(tabName = "home",class = "active",
              dateRangeInput('dateRangeInput',
                             label = 'Date',
                             start = as.Date(max(mydata$date))-2, 
                             end = as.Date(max(mydata$date)),
                             min = as.Date(min(mydata$date)),
                             max = as.Date(max(mydata$date)),
                             format = "yyyy-mm-dd",
                             language = "de"),
              
              fluidRow(
                tabBox(width = 8,
                       tabPanel("Tabelle", rpivotTableOutput("pivotTable",width = "100%", height = "100%"))
                )
              )
      )
    )
  }
  
  # Body of login-Module
  login_body <- function(){
    div(id = "panel", style = "width: 500px; max-width: 100%; margin: 0 auto; padding: 20px;",
        wellPanel(
          tags$h2("LogIn", class = "text-center", style = "padding-top: 0;"),
          
          textInput("user_name", shiny::tagList(shiny::icon("user"), "Username")),
          
          passwordInput("password", shiny::tagList(shiny::icon("unlock-alt"), "Password")),
          
          div(
            style = "text-align: center;",
            actionButton("login_button","LogIn"))
        ),
        
        shinyjs::hidden(
          div(id = "error",
              tags$p("Wrong Password or Username",
                     style = "color: red; font-weight: bold; padding-top: 5px;", class = "text-center"))
        )
    )
  }
  
  
  observeEvent(input$login_button,{
    username_input = input$user_name
    pw_input = input$password
    
    # get pw of user_name stored in user_data
    pw <- user_data%>%
      filter(user==username_input)%>%
      select(password)%>%
      as.character()
    
    # if input pw matches pw stored in db set login to true
    if(pw_input==pw){
      values$login <- TRUE
    }
    # else show error
    else{
      shinyjs::toggle(id = "error", anim = TRUE, time = 1, animType = "fade")
      shinyjs::delay(5000, shinyjs::toggle(id = "error", anim = TRUE, time = 1, animType = "fade"))
    }
  })
  
  
  observeEvent(values$login,{
    # if login-data was valid show dashboard
    if(values$login){
      output$header <- renderUI(auth_header())
      output$body <- renderUI(admin_body())
      output$sidebar <- renderMenu(admin_sidebar())
      shinyjs::removeClass(selector = "body", class = "sidebar-collapse")
    }
    # else show login module
    else{
      output$body <- renderUI(login_body())
      output$header <- renderUI(login_header())
      output$sidebar <- renderMenu(login_sidebar())
      shinyjs::addClass(selector = "body", class = "sidebar-collapse")
    }
  })
  
  # set login to false if user clicks on logout -> go back to login module (see obsereEvent(values$login))
  observeEvent(input$logout_button,{
    values$login <- FALSE
  })
  
  # ----------------------------------------------------------------------
  #     Pivot Tabelle
  # ----------------------------------------------------------------------
  output$pivotTable <- renderRpivotTable({

  pivot_data <-mydata%>%
      filter(date >= input$dateRangeInput[1] & date <= input$dateRangeInput[2])%>%
      select(product,sold,date)

    rpivotTable(
      data = pivot_data, rows = "product",cols="date", vals = "sold",
      aggregatorName = "Sum", rendererName = "Table",
      subtotals = FALSE)
  })
}

# Run the application 
shinyApp(ui = ui, server = server)
@smartinsightsfromdata
Copy link
Owner

@AndreasPhilippi I think the problem is actually in your filtering code.

The following works. Please note that I added the ability to scroll (by design pivotable can add lots of columns or rows, depending on the files you are analysing.

library(shiny)
library(shinydashboard)
library(rpivotTable)
library(magrittr)
library(shinyjs)

mydata <- data.frame(
  product = c('A','B','C','A','B','C','A','B','C'),
  sold = c(5, 10, 15, 7, 6, 5, 9, 3, 1),
  date = as.Date(c('2010-01-01','2010-01-01','2010-01-01','2010-01-02','2010-01-02','2010-01-02','2010-01-03','2010-01-03','2010-01-03'))
)

user_data <- data.frame(
  user = c("Andreas", "Sascha", "Tobias"),
  password = c("123","123","123"), 
  permissions = c("admin","admin","admin"),
  name = c("Andreas", "Sascha", "Tobias"),
  stringsAsFactors = FALSE,
  row.names = NULL
)

ui <- dashboardPage(
  
  # Dashboardheader
  dashboardHeader(uiOutput("header")),
  
  # Dashboardsidebar
  dashboardSidebar(collapsed = FALSE,
                   sidebarMenu(id = "sidebar", sidebarMenuOutput("sidebar"))),
  
  # Dashboardbody
  dashboardBody(
    
    # Turn shinyjs on
    shinyjs::useShinyjs(),
    
    uiOutput("body")
  )
)

server <- function(input, output) {
  values <- reactiveValues()
  # reactive value to trigger the body, sidebar, header of dashboard depending on the login-state 
  values$login <- TRUE
  
  # header of login-Module (nothing in it)
  login_header <- function(){
  }
  
  # header if user is logged in
  auth_header <- function(){
    fluidRow(
      column(12,actionButton("logout_button","Logout",class = "btn-danger", style = "color: white; border-color: #d73925; background: #dd4b39")))
  }
  
  # Sidebar of login-Module (empty)
  login_sidebar <- function(){
    sidebarMenu()
  }
  
  # Sidebar if user is logged in 
  admin_sidebar <- function(){
    
    sidebarMenu(
      menuItem("Home", tabName = "home", icon = icon("home"))
    )
  }
  
  # Body if user is logged in 
  admin_body <- function(){
    tabItems(
      # Body for "Startseite" menuItem  
      tabItem(tabName = "home",class = "active",
              dateRangeInput('dateRangeInput',
                             label = 'Date',
                             start = as.Date(max(mydata$date))-2, 
                             end = as.Date(max(mydata$date)),
                             min = as.Date(min(mydata$date)),
                             max = as.Date(max(mydata$date)),
                             format = "yyyy-mm-dd",
                             language = "de"),
              
              fluidRow(
                tabBox(width = 8
                       , height= 20 #, status = "primary", solidHeader = TRUE
                       , tabPanel( tags$head(tags$style( type = 'text/css',  '#test{ overflow-x: scroll; }'))
                                   , rpivotTableOutput("pivotTable"))
                       # ,tabPanel("Tabelle", rpivotTableOutput("pivotTable"))
                )
              )
      )
    )
  }
  
  # Body of login-Module
  login_body <- function(){
    div(id = "panel", style = "width: 500px; max-width: 100%; margin: 0 auto; padding: 20px;",
        wellPanel(
          tags$h2("LogIn", class = "text-center", style = "padding-top: 0;"),
          
          textInput("user_name", shiny::tagList(shiny::icon("user"), "Username")),
          
          passwordInput("password", shiny::tagList(shiny::icon("unlock-alt"), "Password")),
          
          div(
            style = "text-align: center;",
            actionButton("login_button","LogIn"))
        ),
        
        shinyjs::hidden(
          div(id = "error",
              tags$p("Wrong Password or Username",
                     style = "color: red; font-weight: bold; padding-top: 5px;", class = "text-center"))
        )
    )
  }
  
  
  observeEvent(input$login_button,{
    username_input = input$user_name
    pw_input = input$password
    
    # get pw of user_name stored in user_data
    pw <- user_data%>%
      filter(user==username_input)%>%
      select(password)%>%
      as.character()
    
    # if input pw matches pw stored in db set login to true
    if(pw_input==pw){
      values$login <- TRUE
    }
    # else show error
    else{
      shinyjs::toggle(id = "error", anim = TRUE, time = 1, animType = "fade")
      shinyjs::delay(5000, shinyjs::toggle(id = "error", anim = TRUE, time = 1, animType = "fade"))
    }
  })
  
  
  observeEvent(values$login,{
    # if login-data was valid show dashboard
    if(values$login){
      output$header <- renderUI(auth_header())
      output$body <- renderUI(admin_body())
      output$sidebar <- renderMenu(admin_sidebar())
      shinyjs::removeClass(selector = "body", class = "sidebar-collapse")
    }
    # else show login module
    else{
      output$body <- renderUI(login_body())
      output$header <- renderUI(login_header())
      output$sidebar <- renderMenu(login_sidebar())
      shinyjs::addClass(selector = "body", class = "sidebar-collapse")
    }
  })
  
  # set login to false if user clicks on logout -> go back to login module (see obsereEvent(values$login))
  observeEvent(input$logout_button,{
    values$login <- FALSE
  })
  
  # ----------------------------------------------------------------------
  #     Pivot Tabelle
  # ----------------------------------------------------------------------
  output$pivotTable <- renderRpivotTable({
    
    # pivot_data <-mydata%>%
    #   filter(date >= input$dateRangeInput[1] & date <= input$dateRangeInput[2])%>%
    #   select(product,sold,date)
    # 
    rpivotTable(
      data = mydata
    )
      #   pivot_data, rows = "product",cols="date", vals = "sold",
      # aggregatorName = "Sum", rendererName = "Table",
      # subtotals = FALSE)
  })
}

# Run the application 
shinyApp(ui = ui, server = server)

@AndreasPhilippi
Copy link
Author

AndreasPhilippi commented Sep 30, 2019

Hi, thx for your answer and your time. I tried your code but it still does not work.
After a relog, the table is no longer displayed.

@smartinsightsfromdata
Copy link
Owner

smartinsightsfromdata commented Sep 30, 2019

@AndreasPhilippi This is a bit mysterious & odd.

Have you tried to run the example I've attached, exactly as it is?
As mentioned, it works fine with me. See here.
Screenshot 2019-09-30 at 16 40 36

this is my session info(). Could you provide yours?

sessionInfo()
R version 3.6.1 (2019-07-05)
Platform: x86_64-apple-darwin18.7.0 (64-bit)
Running under: macOS Mojave 10.14.6

Matrix products: default
BLAS:   /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /usr/local/Cellar/openblas/0.3.7/lib/libopenblasp-r0.3.7.dylib

locale:
[1] en_GB.UTF-8/en_GB.UTF-8/en_GB.UTF-8/C/en_GB.UTF-8/en_GB.UTF-8

attached base packages:
[1] stats     graphics  grDevices
[4] utils     datasets  methods  
[7] base     

other attached packages:
[1] shinyjs_1.0         
[2] magrittr_1.5        
[3] rpivotTable_0.3.0   
[4] shinydashboard_0.7.1
[5] shiny_1.3.2         

loaded via a namespace (and not attached):
 [1] Rcpp_1.0.2      packrat_0.5.0  
 [3] digest_0.6.21   later_0.8.0    
 [5] mime_0.7        R6_2.4.0       
 [7] jsonlite_1.6    xtable_1.8-4   
 [9] rlang_0.4.0     promises_1.0.1 
[11] tools_3.6.1     htmlwidgets_1.3
[13] yaml_2.2.0      httpuv_1.5.2   
[15] compiler_3.6.1  htmltools_0.3.6

@AndreasPhilippi
Copy link
Author

AndreasPhilippi commented Oct 1, 2019

@smartinsightsfromdata
Hi, sry for my late reply.
Exactly - I tried to run it as it is.
I also tried running it on a friend's PC, but the same turned out.

This is how it looks like when I run the app:
bild1

And that's what it looks like when I log out and in again

bild2

In addition here the sessionInfo()

R version 3.5.3 (2019-03-11)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows >= 8 x64 (build 9200)

Matrix products: default

locale:
[1] LC_COLLATE=German_Germany.1252  LC_CTYPE=German_Germany.1252    LC_MONETARY=German_Germany.1252
[4] LC_NUMERIC=C                    LC_TIME=German_Germany.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] dplyr_0.8.3          shinyjs_1.0.1.9004   magrittr_1.5         rpivotTable_0.3.0    shinydashboard_0.7.1
[6] shiny_1.3.2         

loaded via a namespace (and not attached):
 [1] Rcpp_1.0.1       rstudioapi_0.10  tidyselect_0.2.5 xtable_1.8-4     R6_2.4.0         rlang_0.4.0      tools_3.5.3     
 [8] pool_0.1.4.2     DBI_1.0.0        dbplyr_1.4.2     htmltools_0.3.6  RMySQL_0.10.17   yaml_2.2.0       assertthat_0.2.0
[15] digest_0.6.19    tibble_2.1.3     crayon_1.3.4     purrr_0.3.2      later_0.8.0      htmlwidgets_1.4  promises_1.0.1  
[22] glue_1.3.1       mime_0.5         compiler_3.5.3   pillar_1.3.1     jsonlite_1.6     httpuv_1.5.1     pkgconfig_2.0.2 ```

@smartinsightsfromdata
Copy link
Owner

smartinsightsfromdata commented Oct 5, 2019

@AndreasPhilippi

I'm keeping investigating the issue. This is what I found:

There has been a regression of sort with the upgrade from htmlwidgets 1.3 to further releases.

Please try to install htmlwidgets 1.3 and confirm. It works for me.

Incidentally, now htmlwidgets 1.5 is out and I cannot test with 1.4 anymore.

There is another regression with the login: with htmlwidgets 1.5 it doesn't work anymore!

Please try to install htmlwidgets 1.3 and confirm (same as 1.5).
I've reported two issues. Let's see what they say.
ramnathv/htmlwidgets#350. - this is about the login not working anymore
ramnathv/htmlwidgets#349 - this is about rpivotTable not working anymore from 1.3 to 1.4 and 1.5.

@smartinsightsfromdata
Copy link
Owner

smartinsightsfromdata commented Oct 6, 2019

@AndreasPhilippi There is a temporary fix (beyond using htmlwidgets 1.3) in ramnathv/htmlwidgets#349. I suggest to follow the evolution there.

@AndreasPhilippi
Copy link
Author

@smartinsightsfromdata
Great, thank you for your help and lets see what turns out for version 1.5!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants