---
title: "Included Modules"
vignette: >
  %\VignetteIndexEntry{Included Modules}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

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

library(formods)
```


# Introduction 

Do you ever make a Shiny app and think: Didn't I just do all this stuff last week? From creating data upload forms to generating a UI for building ggplot figures there are certain components we all use in our apps. The purpose of `formods` is to create customizable Shiny modules to allow many of these components to be created quickly so you can focus on the part of the app that is unique and interesting. Each of the modules in `formods` generates code dynamically to produce the underlying outputs. This allows modules combined under this framework to generate code that allows the state of apps to be reproduced as a single script. 

## Implementation

Each module will have a short name that is used with functions and namespaces. For example the upload data module would use UD. To use a module you need to create the appropriate UI elements as well as call the module server. Both the high level `formods` components and the individual modules are configured through YAML configuration files.  

# Avialable modules

The currently available modules are listed in the table below. The SN column
contains the short name used to identify that module. The individual HTML UI
elements are listed as well as other UI outputs.

```{r, echo = FALSE, eval=TRUE}
curr_mods = FM_fetch_current_mods()
#library(rhandsontable)
#rhandsontable::rhandsontable(curr_mods$df, width=750, rowHeaders = NULL) %>%
#hot_cols(colWidths = c(100, 50, 300, 300)) 

mapping = data.frame(
  col_keys = c("Module", "SN", "htmlOutput", "otherOutput"),
  what     = c("Module", "SN", "htmlOutput", "Other Outputs"),
  stringsAsFactors = FALSE
)

library(flextable)
ft = flextable(curr_mods$df)                       |>
  valign(valign = "top", part = "body")            |>
  set_header_df(mapping = mapping, key="col_keys") |>
  autofit()                                        |>
  theme_vanilla()
ft
```

## Using a module

Using a module requires two components: You need to add UI elements for those in the module, and then you need to add the server component as well. Take care to use the same `id` for both the UI and server components. The UI elements are listed in the table above. Also each module in `formods` contains an example App file which isolates each UI component to allow you to see how it's used. This is called `XX_module_components.R`, where `XX` is the module short name. For example to see an example of the upload data module you could run the following to copy the file locally:

``` r
copy.file(system.file(package="formods", "templates", "UD_module_components.R"), "UD_module_components.R")
``` 

If you want to run the App from within the package you can just do the following:

``` r
runApp(system.file(package="formods", "templates", "UD_module_components.R"))
``` 

### Compact UI elements

Using the module components script above, you can see whate each UI element looks like and how it behaves. This allows you to have granular control over the UI elements and their placement. For each module, `formods` provides a single ui output to place all of the module UI components together. For the upload data module it looks like this:

``` r
htmlOutput(NS("UD", "ui_ud_compact"))
``` 

If you copy the `FM_compact.R` file locally, you can see how these are used for each module: 

``` r
copy.file(system.file(package="formods", "templates", "FM_compact.R"), "FM_compact.R")
```

And you can run this example and see how the modules interact as well:

``` r
runApp(system.file(package="formods", "templates", "FM_compact.R"))
```

### Deployment
To deploy your App you need to create an App file with the appropriate `ui` and `server` functions called `App.R`. This will create one for you:

``` r
file.copy(from = system.file(package="formods", "templates", "FM_compact.R"),
          to   = "App.R")
```

There are certain aspects of the app that behave differently when deployed. To do that you need to indicate that the app is deployed. You can do this in two ways. This is done by setting the `deployed` argument to each of the server functions to `TRUE`.

### Server functions

Each module has a server function that uses the shortname followed by an underscore as the prefix. For example the server function named using the convention: `XX_Server()`. Where `XX` is the module short name. For example the server function for the upload data module is `UD_Server()`. At a minimum the server will take the module ID, a configuration file for the formods package, the module configuration file, and reactive object called `react_state`. The `react_state` object is used to link reactions between the modules.

Again the the different `XX_module_components.R` files shows how to use the server functions for each module. Briefly, using the UD module as an example you would do the following in your app `server` function:

```r
server <- function(input, output, session) {
  react_FM = reactiveValues()

  # Module server
  UD_Server(id="UD", react_state=react_FM)
}
```

### YAML configuration files

Both `formods` and the individual modules are configured through YAML files. By default, the modules will use the included template YAML files. However, you may want to alter the default formatting and text. To do that you simply need to make local copies of the files like this:


``` r
copy.file(system.file(package="formods", "templates", "formods.yaml"), "formods.yaml")
copy.file(system.file(package="formods", "templates", "UD.yaml"), "UD.yaml")
```

You can then modify those files. To use them you need to point the server functions to those instead of the default templates. The following sections describe the current modules and how to use them. 

## App State Management (ASM)

The ASM module is used to manage the app state. This allows the user to save the current app state and load it at a later time.

## Upload Data (UD)

The UD module allows users to upload data files into the App. It will allow you to specify file types and for Excel files the sheet to be used.

Provides 

* Data sets via: `FM_fetch_ds()`  

## Data Wrangling (DW)

The DW module provides an interface to `dplyr` and `tidyr`.These are used to create chains of data wrangling commands that the user can build to transform the data creating **data views**. The DW module can use data from the UD module, or can take in a list with a dataset.

Provides 

* Data views via: `FM_fetch_ds()`  
* Reporting of data views (Excel)

## Figure Generation (FG)

The FG module provides an interface to `ggplot` and allows the user to select from both the original data set from the UD module as well as the data views created in the DW module. The user here can create multiple figures.

Provides 

* Reporting of figures (PowerPoint and Word)

# Known Issues

## 413 Request Entity too large.

If you are running RStudio on a server (through a web browser) and you receive the following message:

`413 Request Entity too large.`

The problem lies in the NGINX server. This is a proxy server being used by RStudio. And the issue is a limit on the maximum upload size in the NGINX server. The solution is to edit the configuration file (something like `/etc/nginx/nginx.conf`) and set the option `client_mx_body_size` to something more reasonable.

## Disconnected from the server

