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_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
valueBox(users_licensed)
valueBox(nrow(users_admins))
valueBox(nrow(users_pubs))
valueBox(nrow(users_viewers))
plot_historical
plot_role
plot_NU
reactable( filter(current_users), searchable = TRUE, highlight = TRUE, resizable = TRUE, filterable = TRUE, width = "100%" )
reactable( filter(current_users, user_role == "administrator"), searchable = TRUE, highlight = TRUE, resizable = TRUE, filterable = TRUE, width = "100%" )
reactable( filter(current_users, user_role == "publisher"), searchable = TRUE, highlight = TRUE, resizable = TRUE, filterable = TRUE, width = "100%" )
reactable( filter(current_users, user_role == "viewer"), searchable = TRUE, highlight = TRUE, resizable = TRUE, filterable = TRUE, width = "100%" )
reactable( historical_users, searchable = TRUE, highlight = TRUE, resizable = TRUE, filterable = TRUE, width = "100%" )
valueBox(total_locks)
valueBox(total_unlocks, caption = "See EULA") # Edgar - conditional format if unlocks are > (nominal value).
# 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.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.