% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/module_snapshot_manager.R
\name{snapshot_manager_module}
\alias{snapshot_manager_module}
\alias{snapshot_manager_ui}
\alias{snapshot}
\alias{snapshot_manager}
\alias{snapshot_manager_srv}
\title{Filter state snapshot management}
\usage{
snapshot_manager_ui(id)

snapshot_manager_srv(id, slices_global, mapping_matrix, filtered_data_list)
}
\arguments{
\item{id}{(\code{character(1)}) \code{shiny} module id}

\item{slices_global}{(\code{reactiveVal}) that contains a \code{teal_slices} object
containing all \code{teal_slice}s existing in the app, both active and inactive}

\item{mapping_matrix}{(\code{reactive}) that contains a \code{data.frame} representation
of the mapping of filter state ids (rows) to modules labels (columns);
all columns are \code{logical} vectors}

\item{filtered_data_list}{non-nested (named \code{list}) that contains \code{FilteredData} objects}
}
\value{
Nothing is returned.
}
\description{
Capture and restore snapshots of the global (app) filter state.
}
\details{
This module introduces snapshots: stored descriptions of the filter state of the entire application.
Snapshots allow the user to save the current filter state of the application for later use in the session,
as well as to save it to file in order to share it with an app developer or other users,
who in turn can upload it to their own session.

The snapshot manager is accessed through the filter manager, with the cog icon in the top right corner.
At the beginning of a session it presents three icons: a camera, an upload, and an circular arrow.
Clicking the camera captures a snapshot, clicking the upload adds a snapshot from a file
and applies the filter states therein, and clicking the arrow resets initial application state.
As snapshots are added, they will show up as rows in a table and each will have a select button and a save button.
}
\section{Server logic}{

Snapshots are basically \code{teal_slices} objects, however, since each module is served by a separate instance
of \code{FilteredData} and these objects require shared state, \code{teal_slice} is a \code{reactiveVal} so \code{teal_slices}
cannot be stored as is. Therefore, \code{teal_slices} are reversibly converted to a list of lists representation
(attributes are maintained).

Snapshots are stored in a \code{reactiveVal} as a named list.
The first snapshot is the initial state of the application and the user can add a snapshot whenever they see fit.

For every snapshot except the initial one, a piece of UI is generated that contains
the snapshot name, a select button to restore that snapshot, and a save button to save it to a file.
The initial snapshot is restored by a separate "reset" button.
It cannot be saved directly but a user is welcome to capture the initial state as a snapshot and save that.
}

\section{Snapshot mechanics}{

When a snapshot is captured, the user is prompted to name it.
Names are displayed as is but since they are used to create button ids,
under the hood they are converted to syntactically valid strings.
New snapshot names are validated so that their valid versions are unique.
Leading and trailing white space is trimmed.

The module can read the global state of the application from \code{slices_global} and \code{mapping_matrix}.
The former provides a list of all existing \code{teal_slice}s and the latter says which slice is active in which module.
Once a name has been accepted, \code{slices_global} is converted to a list of lists - a snapshot.
The snapshot contains the \code{mapping} attribute of the initial application state
(or one that has been restored), which may not reflect the current one,
so \code{mapping_matrix} is transformed to obtain the current mapping, i.e. a list that,
when passed to the \code{mapping} argument of \code{\link[=teal_slices]{teal_slices()}}, would result in the current mapping.
This is substituted as the snapshot's \code{mapping} attribute and the snapshot is added to the snapshot list.

To restore app state, a snapshot is retrieved from storage and rebuilt into a \code{teal_slices} object.
Then state of all \code{FilteredData} objects (provided in \code{filtered_data_list}) is cleared
and set anew according to the \code{mapping} attribute of the snapshot.
The snapshot is then set as the current content of \code{slices_global}.

To save a snapshot, the snapshot is retrieved and reassembled just like for restoring,
and then saved to file with \code{\link[=slices_store]{slices_store()}}.

When a snapshot is uploaded, it will first be added to storage just like a newly created one,
and then used to restore app state much like a snapshot taken from storage.
Upon clicking the upload icon the user will be prompted for a file to upload
and may choose to name the new snapshot. The name defaults to the name of the file (the extension is dropped)
and normal naming rules apply. Loading the file yields a \code{teal_slices} object,
which is disassembled for storage and used directly for restoring app state.
}

\section{Transferring snapshots}{

Snapshots uploaded from disk should only be used in the same application they come from,
\emph{i.e.} an application that uses the same data and the same modules.
To ensure this is the case, \code{init} stamps \code{teal_slices} with an app id that is stored in the \code{app_id} attribute of
a \code{teal_slices} object. When a snapshot is restored from file, its \code{app_id} is compared to that
of the current app state and only if the match is the snapshot admitted to the session.
}

\author{
Aleksander Chlebowski
}
\keyword{internal}
