---
title: "Bookmark Modules Example"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{bookmark-module}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
```

## Introduction

The `shinystate` package was greatly inspired by an [example application](https://github.com/jcheng5/rpharma-demo) created by Joe Cheng (creator of Shiny) to accompany his keynote presentation at the 2018 [R/Pharma conference](https://rinpharma.com/). Among other notable features as documented in the GitHub repository [README](https://github.com/jcheng5/rpharma-demo/blob/master/README.md), the application provided an alternative user interface powered by Shiny modules to save and restore bookmarkable state. The following example is an adaptation of the original version to utilize `shinystate` to manage the bookmarkable state features.

## How to Run Application

The application source code is included in the 'shinystate' package and it can be launched with the following code:

```{r run-app-package, eval=FALSE}
library(shiny)
library(shinystate)
runExample("bookmark_module", package = "shinystate")
```

If you are viewing this package vignette in a web browser, the application can also be viewed using the Shinylive service:

```{r shinylive_url, echo = FALSE, results = 'asis'}
code <- paste0(
  c(
    "webr::install('shinystate', repos = c('https://rpodcast.r-universe.dev', 'https://repo.r-wasm.org'))",
    knitr::knit_code$get("utils"),
    knitr::knit_code$get("bookmark-modules"),
    knitr::knit_code$get("filter-module"),
    knitr::knit_code$get("select-module"),
    knitr::knit_code$get("summarize-module"),
    knitr::knit_code$get("main-app")
  ),
  collapse = "\n"
)

url <- roxy.shinylive::create_shinylive_url(code)
cat(sprintf("[Open in Shinylive](%s)\n\n", url))
```

```{r shinylive_iframe, echo = FALSE, out.width = '150%', out.extra = 'style = "position: relative; z-index:1"', eval = knitr::is_html_output() && identical(Sys.getenv("IN_PKGDOWN"), "true")}
knitr::include_url(url, height = "800px")
```

## Application Code

The remainder of this vignette contains the source code of the application. Note that the version included in the package is constructed with separate R scripts containing the module and utility function code.

The same principles for using `shinystate` in an application apply in this example as well, but here are specific notes for the implementation used in this example application:

* The module `bookmark_mod` contains a parameter for the `StorageClass` instance used for the application.
* Bookmarkable state sessions are displayed using an interactive table produced by `DT::datatable()` with the ability to select the row used to restore a saved session. This is just one approach to display sessions in a Shiny application.
* The `reactive_sessions()` method is used with a trigger to automatically refresh the session list when the modal opens, after saving, or after deleting a session.
* A reactive object `session_choice` corresponding to the `url` value of the selected row in the sessions table is supplied to the `restore()` method of the `StorageClass` instance.
* A custom bookmark name entered in a text input plus the bookmark id and a timestamp are saved as part of the bookmarkable state snapshot metadata. These are assembled as a `list()` object with named elements for each variable. Other custom scalar metadata about the bookmark could also be captured.

### `app.R`

```{r main-app, eval=FALSE, code=readLines(system.file("examples-shiny/bookmark_module/app.R", package = "shinystate"))[-(6:11)]}
```

### `bookmark_modules.R`

```{r bookmark-modules, eval=FALSE, code=readLines(system.file("examples-shiny/bookmark_module/modules/bookmark_module.R", package = "shinystate"))}
```

### `filter_module.R`

```{r filter-module, eval=FALSE, code=readLines(system.file("examples-shiny/bookmark_module/modules/filter_module.R", package = "shinystate"))}
```

### `select_module.R`

```{r select-module, eval=FALSE, code=readLines(system.file("examples-shiny/bookmark_module/modules/select_module.R", package = "shinystate"))}
```

### `summarize_module.R`

```{r summarize-module, eval=FALSE, code=readLines(system.file("examples-shiny/bookmark_module/modules/summarize_module.R", package = "shinystate"))}
```

### `utils.R`

```{r utils, eval=FALSE, code=readLines(system.file("examples-shiny/bookmark_module/helpers/utils.R", package = "shinystate"))}
```
