-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
update documentation and README (#131)
- Loading branch information
1 parent
4e9d349
commit 628f9a3
Showing
2 changed files
with
78 additions
and
81 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,11 +8,20 @@ | |
4. [Implementation Notes](#implementation-notes) | ||
5. [Configuration](#configuration) | ||
|
||
- [Node Properties](#shared-node-properties) | ||
- [DefaultNode](#defaultnode) | ||
- [BoolNode](#boolnode) | ||
- [Help Content](#help-content) | ||
- [Environment Variables](#environment-variables) | ||
- [The Manifest Game Docs](#the-manifest-game-docs) | ||
- [Table of Contents](#table-of-contents) | ||
- [Introduction](#introduction) | ||
- [Specification](#specification) | ||
- [Nomenclature](#nomenclature) | ||
- [Implementation Notes](#implementation-notes) | ||
- [Configuration](#configuration) | ||
- [Shared Node Properties](#shared-node-properties) | ||
- [DefaultNode](#defaultnode) | ||
- [BoolNode](#boolnode) | ||
- [Help Content](#help-content) | ||
- [Environment Variables](#environment-variables) | ||
- [Deployment](#deployment) | ||
- [Future Work](#future-work) | ||
|
||
6. [Deployment](#deployment) | ||
7. [Future Work](#future-work) | ||
|
@@ -24,68 +33,68 @@ The purpose of this project is to create an interactive decision tree that will | |
user's specific use case. It's intended to be a publicly available tool to assist (i.e., no sensitive information is | ||
displayed or authentication is required). | ||
|
||
|
||
|
||
## Specification | ||
|
||
The decision tree is a series of questions that will guide the user to the appropriate help content, or directly answer | ||
The decision tree is a series of questions that will guide the user to the appropriate help content, or answer | ||
the user's questions directly in the graph. | ||
|
||
The decision tree should meet the following requirements for a minimum viable product (MVP): | ||
|
||
1. The decision tree is be interactive, allowing the user to navigate the tree by clicking on the appropriate | ||
nodes of the tree or buttons. | ||
2. The decision tree is be able to be embedded in a web page. | ||
3. The tree should walk the user through the process of electronically manifesting hazardous waste. | ||
2. The decision tree should accessible through a browser | ||
3. The decision tree should be accessible to users who need require assistive technology (AT) to interact with the decision tree. The tree should... | ||
- be navigable without a mouse. | ||
- indicate the choices made to users with limited/no vision. | ||
- not include audio cues or information without visual content that conveys the same inforation. | ||
|
||
## Nomenclature | ||
|
||
The following terms are used throughout the documentation and code: | ||
|
||
1. **Node**: A node is a vertex in the decision tree. We have multiple types of nodes: | ||
such as "Yes/No" nodes (`BoolNode`) and default nodes (`DefaultNode`). | ||
2. **Edge**: An edge is a connection between two nodes. The edge is directed from the parent node to the child node. | ||
3. **Decision Tree**: The decision tree is the entire graph of nodes and edges. The decision tree must be a directed | ||
acyclic graph (DAG) to prevent infinite loops. In the future, we plan on allowing users to create the decision tree | ||
with a config file (again, there must be no cycles in the graph). | ||
4. **Children**: The children of a node are the vertices that are **_directly_** connected to the parent node by a | ||
direct edge such that in the topological order `f(u, v)` of the DAG, for every edge `(u, v)`, where `u` is the parent | ||
of `v`, `u` comes before `v`. (you will see this term in the code many times, see "Descendant") | ||
5. **Descendant** (or **Descendants**): The descendants of a node are the vertices that are connected to the parent node | ||
Before reading the docs or code, it is helpful to be familar with [Directed Acyclic Graphs](https://en.wikipedia.org/wiki/Directed_acyclic_graph). | ||
|
||
The following terms are used throughout the source: | ||
|
||
1. **Directed Acyclic Graph** a graph that consist of vertices and edges, with each edge directed | ||
from one vertex to another, such that following those directions will never form a closed loop. | ||
2. **Node**: A node is the implementation of a vertex in the decision tree and represents a choice. | ||
We have multiple types of nodes: such as "Yes/No" nodes (`BoolNode`) and default nodes (`DefaultNode`). | ||
3. **Edge**: An edge is a connection between two nodes. The edge is directed from the parent node to the child node. | ||
4. **Decision Tree**: The decision tree is the graph of choices. The decision tree must be a directed | ||
acyclic graph (DAG) to prevent infinite loops. | ||
5. **Children**: The children of a node are the nodes that are **_directly_** connected to the parent node by a | ||
edge such that in the topological order `f(u, v)` of the DAG, for every edge `(u, v)`, where `u` is the parent | ||
of `v`, `u` comes before `v`. (also see "Descendant") | ||
6. **Descendant**: The nodes that are connected to the parent node | ||
by a path of edges such that in the topological order `f(u, v)` of the DAG, for every edge `(u, v)`, where `u` is the | ||
parent of `v`, `u` comes before `v`. (you will see this term in the code many times) | ||
6. **Parent**: The parent of a node is the vertex that is connected to the child node by a direct edge such that in the | ||
parent of `v`, `u` comes before `v`. | ||
7. **Parent**: The parent of a node is the vertex that is connected to the child node by a direct edge such that in the | ||
topological order `f(u, v)` of the DAG, for every edge `(u, v)`, where `u` is the parent of `v`, `u` comes | ||
before `v`. | ||
(you will see this term in the code many times) | ||
7. **Sibling**: The siblings of a node are the vertices that are connected to the same parent node as the child node. | ||
8. **Sibling**: The siblings of a node are the vertices that are connected to the same parent node as the child node. | ||
Siblings have the same "rank" in the DAG. | ||
8. **_Nibling_**: The niblings of a node are the descendants of the node's siblings (those that reside at the same level | ||
or rank in the | ||
DAG) | ||
9. **_Nibling_**: The niblings of a node are the descendants of the node's siblings (those that reside at the same level | ||
or rank in the DAG) | ||
|
||
## Implementation Notes | ||
|
||
This project is implemented using [React](https://reactjs.org/) and the [react-flow](https://reactflow.dev/) library. | ||
This project is implemented using the [React](https://reactjs.org/) library and ecosystem | ||
which made prototyping possible in a short amount of time. | ||
|
||
A dependency that came with the react-flow library is [zustand](https://github.com/pmndrs/zustand), a state management | ||
library that is gaining popularity in the React community. We use this library to manage the state of the decision tree. | ||
It does not cost us on bundle size as (A) it already was included as a dependency of react-flow and (B) it is a very | ||
small library. We avoid using the state hooks directly in the UI and wrap that functionality in a custom hooks. | ||
|
||
We, essentially, keep two copies of the decision tree in memory: one as an array of nodes (used by the react-flow | ||
library) and | ||
one as a map (really it's a typescript Record at the moment) which we call the tree. We operate on the tree and then | ||
convert it to an array when we need to display it. Currently, this works, but we may need to rethink this approach. | ||
Another dependency of note is [zustand](https://github.com/pmndrs/zustand), a popular state management | ||
library. We use this library to manage the global state of the decision tree. We use the devtools | ||
middleware, which allows developers to use the redux dev tools in their local development environment. | ||
|
||
## Configuration | ||
|
||
The decision tree is read from a configuration file. A configuration file is a JSON file that contains all nodes in the | ||
tree, and any accompanying metadata. The configuration file is fetched from the server, read, and parsed at runtime to | ||
build the decision tree. These are stored in the `public/` directory, in particular the `public/default.json` file will | ||
be | ||
loaded by default (see future work). | ||
The decision tree is read from a JSON configuration file that contains all choices in the | ||
tree, and any accompanying metadata. The decision tree config files are stored in the `public/` directory, | ||
which is included in the bundled artifact at build time. Configs are fetched from the server, read, and parsed at runtime to | ||
build the decision tree. In particular the `public/default.json` tree config file is loaded by default | ||
when the user first visits the page. | ||
|
||
The configuration should reflect the following example: | ||
The decision tree config should follow the below example: | ||
|
||
```json | ||
{ | ||
|
@@ -104,10 +113,7 @@ The configuration should reflect the following example: | |
"id": "goRegister", | ||
"data": { | ||
"label": "Time to Register in RCRAInfo!", | ||
"children": [ | ||
"test1", | ||
"test2" | ||
], | ||
"children": [], | ||
"help": "register.json" | ||
} | ||
} | ||
|
@@ -124,15 +130,13 @@ requires a different configuration. | |
short descriptive name (e.g., `goRegister`). | ||
- **type**: The optional type of the node. If no value specified, a default node will be created. The type determines | ||
the behavior of the node. The type is a string that corresponds to the name of the node class (e.g., `BoolNode`). | ||
- **data**: An object that contains the node's metadata. The metadata is different for each node type. | ||
- Possilbe values: `"BoolNode"`, `"Default"`, or left blank. | ||
- **data**: An object that contains the node's metadata. including the children of a node. | ||
- **data.label**: The text that will be displayed on the node. This is the question or statement that the node | ||
represents. | ||
- **data.help**: A boolean value that determines if the node has help content. If true, the node will display a help | ||
icon | ||
that will display help content when clicked. | ||
- **data.help**: A boolean value that determines if the node has help content. If true, the decision tree expects to be | ||
able to find a JSON file in `public/help/` with the same name as the node id. A question mark icon will be displayed | ||
on node if true. See [Help Content](#help-content) for more information. | ||
- **data.help**: A string value corresponding to a JSON or HTML file in the `public/help/` directory. | ||
If present, the node will display a question mark icon that, when clicked, | ||
will fetch and render the JSON/HTML file (see [help content](#help-content)). | ||
|
||
### DefaultNode | ||
|
||
|
@@ -158,26 +162,23 @@ requires a different configuration. | |
|
||
```json | ||
{ | ||
"id": "likeToPlatAGame", | ||
"id": "wouldULikeToPlayAGame", | ||
"type": "BoolNode", | ||
"data": { | ||
"label": "Would you like to play a game?", | ||
"yesId": "sureWhyNot", | ||
"noId": "noThankYou", | ||
"help": true | ||
"help": "game-instructions.html" | ||
} | ||
} | ||
``` | ||
|
||
### Help Content | ||
|
||
Nodes can optionally have help content, which can be useful for providing additional information to the user when the | ||
node merits further explanation. The help content is stored in the `public/help/` directory. The JSON representation of | ||
the decision tree should include the file name (e.g., `help.html`) in the `"help"` field of the node's data object. | ||
|
||
Currently, we support text and HTML based content. | ||
Some choices should have additional information to accomapny the node label. | ||
The help content is stored in the `public/help/` directory and can either be a JSON or HTML file. | ||
|
||
JSON encoded content should follow the below schema. See [future work](#future-work). | ||
JSON encoded content should follow the below schema. | ||
|
||
```json | ||
{ | ||
|
@@ -192,20 +193,19 @@ A list of environment variables that can be used to configure the application ca | |
These variables are passed at build time, see the [Vite documentation](https://vitejs.dev/guide/env-and-mode.html) for | ||
further details. | ||
|
||
A couple of things that can be configured are the app title (default: 'The Manifest Game') and the issue | ||
For example, things that can be configured are the app title (default: 'The Manifest Game') and the issue | ||
tracker URL (default: 'mailto:[email protected]'). | ||
|
||
## Deployment | ||
|
||
The development server can be started using the npm run dev command. This will start a server on port 3000 (by default). | ||
The project currently uses [vite](https://vitejs.dev/) as the development server, bundler, and build tool. | ||
|
||
The project is a static site, any method of deploying static files will work (e.g., AWS S3, raspberry pi in the | ||
basement, etc.). | ||
|
||
This project config files also include a Dockerfile and a docker-compose file, both of which are fairly straightforward. | ||
Both will deploy the project on port 3000 behind [Nginx](https://www.nginx.com/). The docker-compose | ||
just makes to easier to build, run, and expose the project on port 3000 locally if you don't have a supported version of | ||
just makes it easier to locally build, run, and expose the project on port 3000 if you don't have a supported version of | ||
node installed. | ||
|
||
```shell | ||
|
@@ -214,10 +214,7 @@ docker compose up | |
|
||
## Future Work | ||
|
||
1. It should be possible to link to a specific node in the decision tree so that the tree starts at that node open upon | ||
visiting the page. | ||
2. A new custom node type for multiple choice questions (e.g., what type of site are you? A generator, a TSDF, or a | ||
transporter). | ||
3. Allow EPA to create multiple tree for users. | ||
4. Markup help text. Currently, we only support text based help content, stored in a JSON encoded file. Being able to | ||
provide more complex help content could make the tool more useful as it would allow linking to other resources. | ||
- [x] It should be possible to link to a specific node in the decision tree so that the tree starts at that node open upon visiting the page. | ||
- [ ] A node type for multiple choice questions (e.g., what type of site are you? A generator, a TSDF, or a transporter). | ||
- [ ] Allow EPA to create multiple tree for users. | ||
- [x] Markup help text. Currently, we only support text based help content, stored in a JSON encoded file. Being able to provide more complex help content could make the tool more useful as it would allow linking to other resources. |