Skip to content

Commit 1fc9594

Browse files
authored
feat: add "content scope" control to megadashboard (#86)
* add content scope control * shrink cache, improve performance * reduce scope of scope control * improve messaging * further simplify scope controls * better messaging for zero data
1 parent a9c00c0 commit 1fc9594

File tree

1 file changed

+84
-23
lines changed
  • extensions/who-is-visiting-this-content

1 file changed

+84
-23
lines changed

extensions/who-is-visiting-this-content/app.R

Lines changed: 84 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,11 @@ ui <- function(request) {
119119
# Controls shown only when the outer table is displayed
120120
conditionalPanel(
121121
"input.content_guid == null",
122+
selectizeInput(
123+
"content_scope",
124+
"Included Content",
125+
choices = NULL
126+
),
122127
selectizeInput(
123128
"app_mode_filter",
124129
label = "Filter by Content Type",
@@ -328,6 +333,16 @@ server <- function(input, output, session) {
328333
)
329334
})
330335

336+
# "Clear filter x" link ----
337+
338+
observeEvent(input$clear_selection, {
339+
updateSelectizeInput(
340+
session,
341+
"selected_users",
342+
selected = NA
343+
)
344+
})
345+
331346
# Cache invalidation button ----
332347

333348
cache <- cachem::cache_disk("./app_cache/cache/")
@@ -407,22 +422,53 @@ server <- function(input, output, session) {
407422

408423
# Load and processing data ----
409424

410-
# The cache operates on a per-user basis, since different users see different
411-
# content.
412-
authed_user_guid <- client$me()$guid
425+
active_user_info <- client$me()
413426

414-
date_range <- reactive({
415-
switch(input$date_range_choice,
416-
"1 Week" = list(from = today() - days(6), to = today()),
417-
"30 Days" = list(from = today() - days(29), to = today()),
418-
"90 Days" = list(from = today() - days(89), to = today()),
419-
"Custom" = list(from = input$date_range_custom[1], to = input$date_range_custom[2])
427+
active_user_guid <- active_user_info$guid
428+
429+
# Allow the user to control the content they can see.
430+
active_user_role <- active_user_info$user_role
431+
432+
scope_choices <- switch(active_user_role,
433+
"administrator" = list(
434+
"All Content" = "all",
435+
"Owned + Collaborating" = "edit",
436+
"Owned" = "own"
437+
),
438+
list(
439+
"Owned + Collaborating" = "edit",
440+
"Owned" = "own"
420441
)
442+
)
443+
444+
observe({
445+
req(scope_choices)
446+
updateSelectizeInput(session, "content_scope", choices = scope_choices, selected = scope_choices[1])
421447
})
422448

423-
content <- reactive({
449+
content_unscoped <- reactive({
424450
get_content(client)
425-
}) |> bindCache(authed_user_guid)
451+
}) |> bindCache(active_user_guid)
452+
453+
content <- reactive({
454+
req(input$content_scope)
455+
456+
switch(input$content_scope,
457+
"all" = content_unscoped(),
458+
"view" = content_unscoped() |> filter(app_role != "none"),
459+
"edit" = content_unscoped() |> filter(app_role %in% c("owner", "editor")),
460+
"own" = content_unscoped() |> filter(owner_guid == active_user_guid)
461+
)
462+
})
463+
464+
date_range <- reactive({
465+
switch(input$date_range_choice,
466+
"1 Week" = list(from = today() - days(6), to = today()),
467+
"30 Days" = list(from = today() - days(29), to = today()),
468+
"90 Days" = list(from = today() - days(89), to = today()),
469+
"Custom" = list(from = input$date_range_custom[1], to = input$date_range_custom[2])
470+
)
471+
})
426472

427473
users <- reactive({
428474
get_users(client) |>
@@ -431,36 +477,41 @@ server <- function(input, output, session) {
431477
display_name = paste0(full_name, " (", username, ")")
432478
) |>
433479
select(user_guid = guid, full_name, username, display_name, email)
434-
}) |> bindCache(authed_user_guid)
480+
}) |> bindCache(active_user_guid)
435481

436482
usage_data_raw <- reactive({
483+
req(active_user_role %in% c("administrator", "publisher"))
437484
get_usage(
438485
client,
439486
from = date_range()$from,
440487
to = date_range()$to
441488
)
442-
}) |> bindCache(authed_user_guid, date_range())
489+
}) |> bindCache(active_user_guid, date_range())
443490

444491
# Multi-content table data ----
445492

446-
# Filter the raw data based on app mode and visit merge window
493+
# Filter the raw data based on selected scope, app mode and visit merge window
447494
usage_data_visits <- reactive({
448-
filtered_data <- if (length(input$app_mode_filter ) == 0) {
449-
usage_data_raw()
495+
req(content())
496+
scope_filtered_usage <- usage_data_raw() |>
497+
filter(content_guid %in% content()$guid)
498+
499+
app_mode_filtered_usage <- if (length(input$app_mode_filter ) == 0) {
500+
scope_filtered_usage
450501
} else {
451502
app_modes <- unlist(app_mode_groups[input$app_mode_filter])
452503
filter_guids <- content() |>
453504
filter(app_mode %in% app_modes) |>
454505
pull(guid)
455-
usage_data_raw() |>
506+
scope_filtered_usage |>
456507
filter(content_guid %in% filter_guids)
457508
}
458509

459510
req(input$visit_merge_window)
460511
if (input$visit_merge_window == 0) {
461-
filtered_data
512+
app_mode_filtered_usage
462513
} else {
463-
filtered_data |>
514+
app_mode_filtered_usage |>
464515
group_by(content_guid, user_guid) |>
465516

466517
# Compute time diffs and filter out hits within the session
@@ -474,6 +525,7 @@ server <- function(input, output, session) {
474525

475526
# Create data for the main table and summary export.
476527
multi_content_table_data <- reactive({
528+
req(nrow(usage_data_visits()) > 0)
477529
usage_summary <- usage_data_visits() |>
478530
group_by(content_guid) |>
479531
summarize(
@@ -504,10 +556,19 @@ server <- function(input, output, session) {
504556
# Multi-content table UI and outputs ----
505557

506558
output$summary_text <- renderText(
507-
glue::glue(
508-
"{nrow(usage_data_visits())} visits ",
509-
"across {nrow(multi_content_table_data())} content items."
510-
)
559+
if (active_user_role == "viewer") {
560+
"Viewer accounts do not have permission to view usage data."
561+
} else if (nrow(usage_data_visits()) == 0) {
562+
paste(
563+
"No usage data available.",
564+
"Try adjusting your content filters or date range."
565+
)
566+
} else {
567+
glue::glue(
568+
"{nrow(usage_data_visits())} visits ",
569+
"across {nrow(multi_content_table_data())} content items."
570+
)
571+
}
511572
)
512573

513574
output$content_usage_table <- renderReactable({

0 commit comments

Comments
 (0)