require(tidyverse)
require(flexdashboard)
require(ggrepel)
devtools::load_all()

Sidebar {.sidebar data-width=300}

Plot setup

checkboxInput('cadence_markers', 'Plot Agile events', value = TRUE)
checkboxInput('personal_markers', 'Plot personal markers', value = TRUE)
checkboxInput('today', 'Plot today marker', value = TRUE)
checkboxInput('jitter', 'Jitter overlapping markers', value = TRUE)

Role(s)

checkboxInput('role_po', 'Product owner', value = TRUE)
checkboxInput('role_rte', 'Release train engineer', value = TRUE)
checkboxInput('role_sm', 'Scrum master', value = TRUE)
actionButton('load_default', 'Show default config')

Viewer

cfg <- eventReactive(c(input$load_default, input$activate), {
  req(input$config)
  read_config(cfg_content = input$config)
})
acc <- reactive({
  req(cfg())

  res <- generate_calendar(cfg = cfg())
  if (input$jitter) {
    res <- res %>%
      group_by(increment, iteration_wk) %>%
        mutate(dstamp = if_else(is.na(type),
                                dstamp,
                                dstamp + seq(from = 0, by = lubridate::dhours(10),
                                             length.out = dplyr::n()))) %>%
      ungroup()
  }

  return(res)
})

Viewer {.tabset}

Visual

renderPlot({
  validate(need(acc(), message = 'Waiting to complete generating the calendar'))

  d <- isolate(acc())
  if (!input$role_po) d <- d %>% filter(!grepl('^po', tolower(event)))
  if (!input$role_rte) d <- d %>% filter(!grepl('^rte', tolower(event)))
  if (!input$role_sm) d <- d %>% filter(!grepl('^sm', tolower(event)))

  p <- plot_calendar(cal = d)

  if (input$cadence_markers) p <- p + plot_markers(cal = d, markers = 'agile_events')
  if (input$personal_markers) p <- p + plot_markers(cal = d, markers = 'markers')
  if (input$today) p <- p + today_marker()

  return(p)
})

Calendar

Not implemented yet.

Configuration

Configuration {data-height=900}

textAreaInput('config', label = NULL, width = '100%', rows = 20,
              placeholder = 'Enter or load configuration YAML')
observeEvent(input$load_default, {
  cfg_file <- pkgload::package_file('inst/default_config.yml')
  d <- readLines(con = cfg_file)
  updateTextAreaInput(session, 'config', value = paste(d, collapse = '\n'))
})

Note {data-height=100}

Note that the YAML configuration needs to have the appropriate indentation which is difficult to maintain with a proportional font. The advised way of working is to load the default configuration, save it to disk and edit in an appropriate text editor, to then upload for minimal adjustments here.

Buttons {data-height=100}

fluidRow(
  column(width = 5,
         fileInput('cfg_upload', label = NULL, accept = c('yml', 'yaml'))),
  column(width = 5,
         actionButton('load_default', 'Load default configuration')),
 )
fluidRow(
  column(width = 5,
         actionButton('activate', 'Use new values')),
  column(width = 5,
         downloadButton('export', 'Export configuration'))
)
observeEvent(input$cfg_upload, {
  cfg_raw <- paste(readLines(input$cfg_upload$datapath), collapse = '\n')
  updateTextAreaInput(session, 'config', value = cfg_raw)
})
output$export <- downloadHandler(
  filename = 'agile_configuration.yml',
  content = function(f) {
    yaml::write_yaml(input$config, file = f)
  }
)

Cal Table

renderTable({
  acc() %>% mutate(dstamp = format(dstamp, '%Y-%m-%d'))
})


paullemmens/agilecalendar documentation built on March 11, 2023, 1:51 p.m.