library(rscview)
library(flexdashboard)
library(connectapi)
library(tidyverse)
library(lubridate)
library(reactable)
library(ggplot2)
library(ggiraph)
check_envvars()
conn <- create_connection()

# logs <- get_audit_logs(conn, limit = Inf)
logs <- read_rds(here::here("inst", "user-report", "logs_2021-07-02.rds"))
users_tbl <- get_users_tbl(conn)

historical_users <- get_user_historical_tbl(users_tbl = users_tbl)
current_users <- get_user_current_tbl() 

``` {r current} users_licensed <- current_users %>% count() %>% pull()

users_recent <- current_users %>% get_users_daysback(30) %>% count() %>% pull()

users_ninety <- current_users %>% get_users_daysback(90) %>% count() %>% pull()

day_ranges <- current_users %>% count(days_sort, days_range, name = "users") %>% ungroup() %>% mutate( days_sort = as.numeric(days_sort), percent = round(users / sum(users), 2), label = paste0(users, "(", percent * 100 ,"%)") )

users by roles

users_admins <- current_users %>% get_users_role("administrator")

users_pubs <- current_users %>% get_users_role("publisher")

users_viewers <- current_users %>% get_users_role("viewer")

```r
# When were users added to the server? Help me understand the trend in adding users. 

# filter audit logs for locking activities
lock_history <- logs %>% get_lock_history_tbl()

# user creation history -- I'm doing this from the get_user dataframe and not from the audit logs because the audit logs can show user creation under the events of "add_user" or "add_group_member" depending on the auth mechanism. Colorado has this split in the data in how users are added.  
creation_history <- historical_users %>% 
  select(username, created_time) %>% 
  mutate(event = "created") %>% 
  dplyr::rename("event_time" = created_time) %>% 
  arrange(event_time) 


#when do users drop off the NU count? Identify date they no longer counted.
drop_off_history <- historical_users %>% 
  select(username, days_since_active, active_time) %>% 
  filter(as_date(active_time) < (today() - dyears(1))) %>% 
  mutate(event_time = as_date(active_time) + dyears(1)) %>% 
  select(-days_since_active, -active_time) %>% 
  mutate(event = "dropped")
event_history <- bind_rows(creation_history, lock_history, drop_off_history) %>% 
  left_join(select(historical_users, username, active_time), by = "username" ) %>% 
  arrange(event_time) %>% 
  mutate(event_date = as.Date(event_time)) %>% 
  # mutate(active_last_year = case_when(as_date(active_time) < (today() - dyears(1)) ~ FALSE, 
  #                                   as_date(active_time) >= (today() - dyears(1)) ~ TRUE)) %>% 
  mutate(active_last_year = case_when(
                              as_date(active_time) < (event_time - dyears(1)) ~ FALSE, 
                              as_date(active_time) >= (event_time - dyears(1)) ~ TRUE)) %>% 
  group_by(username) %>% 
  arrange(username, event_time) %>%
  mutate(multiple_events = case_when(
    n() > 1 ~ TRUE, 
    TRUE ~ FALSE)) %>% 
  mutate(effect = event) %>% 
  mutate(prior_effect = 
           case_when(
             row_number() == 1 ~ event,
             multiple_events == T & active_last_year == T & row_number() > 1 ~ lag(event, 1),
             multiple_events == T & active_last_year == F ~ "dropped")) %>% 
  mutate(result = case_when(
      prior_effect == "created" & effect == "created" ~ 1,
      prior_effect == "created" & effect == "dropped" ~ -1, 
      prior_effect == "created" & effect == "locked" ~ -1, 
      prior_effect == "created" & effect == "unlocked" ~ 0,
      prior_effect == "dropped" & effect == "created" ~ 1,
      prior_effect == "dropped" & effect == "dropped" ~ 0, 
      prior_effect == "dropped" & effect == "locked" ~ 0, 
      prior_effect == "dropped" & effect == "unlocked" ~ 0,
      prior_effect == "locked" & effect == "created" ~ 1,
      prior_effect == "locked" & effect == "dropped" ~ 0, 
      prior_effect == "locked" & effect == "locked" ~ 0, 
      prior_effect == "locked" & effect == "unlocked" ~ 1,
      prior_effect == "unlocked" & effect == "created" ~ 0,
      prior_effect == "unlocked" & effect == "dropped" ~ -1, 
      prior_effect == "unlocked" & effect == "locked" ~ -1, 
      prior_effect == "unlocked" & effect == "unlocked" ~ 0)) %>% 
  relocate(effect, .after = prior_effect) %>%
  ungroup() %>% 
  arrange(event_time) %>% 
  mutate(usercount = cumsum(result))

# Historical named user plot
plot_NU <- ggplot(event_history, aes(x = event_time, y = usercount, color = event)) +
  geom_step(color = "#4C8187") +
  geom_point(alpha = 0.6) +
  labs(x = "Date", y = "Named Users", title = "Historical Named Users") +
  theme(legend.position="bottom") +
  geom_hline(yintercept = users_licensed) 


add_history <- creation_history %>% 
  mutate(user_add_num = row_number()) %>% 
  mutate(active_in_last_year = case_when(username %in% drop_off_history$username ~ FALSE,
                            TRUE ~ TRUE))

### TODO - IDEA - use a chart like this for user history: 
### http://www.r-graph-gallery.com/318-custom-dygraphs-time-series-example.html
### 



# Historical user additions
plot_historical <- ggplot(add_history, aes(x = event_time, y = user_add_num, color = active_in_last_year)) +
  geom_step(color = "#4C8187") +
  geom_point(alpha = 0.3) +
  labs(x = "Date", y = "Number of Users Added to Server", title = "Historical User Additions") +
  theme(legend.position="bottom") 

# Additions by role
history_role <- add_history %>% left_join(select(historical_users, username, user_role), by = "username")

plot_role <- ggplot(history_role, aes(x = event_time, y = user_add_num, color = active_in_last_year)) +
  facet_grid(. ~ user_role) +
  geom_step(color = "#4C8187") +
  geom_point(alpha = 0.3) +
  labs(x = "Date", y = "Number of Users Added to Server", title = "Historical User Additions") +
  theme(legend.position="bottom")
#User locking frequency
lock_history <- event_history %>% select(username, event_date, event) %>% 
  filter(event == "locked" | event == "unlocked") %>% 
  group_by(username) %>%
  mutate(multiple_events = case_when(
    n() > 1 ~ TRUE, 
    TRUE ~ FALSE)) %>% 
  mutate(subsequently_unlocked = case_when(
    multiple_events == FALSE ~ FALSE,
    multiple_events == TRUE & event == "locked" & lead(event, 1) == "unlocked" ~ TRUE,
    multiple_events == TRUE & event == "locked" & is.na(lead(event, 1)) ~ FALSE )) %>% 
  filter(event == "locked") %>% select(-multiple_events, -event) %>% 
  ungroup() %>% 
  rename("Lock Date" = event_date, "Subsequently Unlocked" = subsequently_unlocked)

# We want total number of locking events in time period and number of unlock events. 
total_locks <- event_history %>% filter(event == "locked") %>% tally() %>% pull()
total_unlocks <- event_history %>% filter(event == "unlocked") %>% tally() %>% pull()
# User profile information

# How many users are active in the last 3 mo, 6 mo, 9 mo, and what fraction of users added phase out? <- this last one can get skewed - if people leave the co, interns, etc. its not that they phased out due to lack of interest.  I am uncertain about building these elements out.  leads people to assume activity level equates to value

User Counts

Row

Licensed Named Users

valueBox(users_licensed)

Administrators

valueBox(nrow(users_admins))

Publishers

valueBox(nrow(users_pubs))

Viewers

valueBox(nrow(users_viewers))

Row{.tabset .tabset-fade}

Historical Users

plot_historical

Historical Users by Role

plot_role

Named User History

plot_NU

Row{.tabset .tabset-fade}

All Named Users

reactable(
  filter(current_users), searchable = TRUE, highlight = TRUE, resizable = TRUE,
  filterable = TRUE, width = "100%"
  )

Administrators

reactable(
  filter(current_users, user_role == "administrator"), searchable = TRUE, highlight = TRUE, resizable = TRUE,
  filterable = TRUE, width = "100%"
  )

Publishers

reactable(
  filter(current_users, user_role == "publisher"), searchable = TRUE, highlight = TRUE, resizable = TRUE,
  filterable = TRUE, width = "100%"
  )

Viewers

reactable(
  filter(current_users, user_role == "viewer"), searchable = TRUE, highlight = TRUE, resizable = TRUE,
  filterable = TRUE, width = "100%"
  )

All Historical Users

reactable(
  historical_users, searchable = TRUE, highlight = TRUE, resizable = TRUE,
  filterable = TRUE, width = "100%"
  )

User Management

Row

Total Locks

valueBox(total_locks)

Total Unlocks

valueBox(total_unlocks, caption = "See EULA") # Edgar - conditional format if unlocks are > (nominal value). 

Row

User Lock Frequency Details

# User Lock Events
reactable(lock_history, rowStyle = function(index){
  if(lock_history[index, "Subsequently Unlocked"] == TRUE){
    list(color = "red")
  }
})
# refer to RStudio EULA and Software License Descriptions. Under RStudio Connect's Named User license, you may permanently terminate (lock) a Named User's use of the Software and assign the Named User's license to a new Named User. For example, if a Named User ceases to use the Software or ceases to be employed by you, you may re-assign their Named User License to a new Named User. Locking is intended to be a permanent action.


kmasiello/rscview documentation built on Jan. 3, 2023, 2:58 p.m.