diff --git a/README.md b/README.md deleted file mode 100644 index c503e55dd..000000000 --- a/README.md +++ /dev/null @@ -1,72 +0,0 @@ -# Help - -## Introduction -DomainViz allows users to identify and visualize protein domains on one or more protein sequences using multiple domain prediction platforms (Pfam and Prosite) to understand the consensus positionality and abundance of different domains within protein groups and families. While Pfam and Prosite each individually provide domain information for a single sequence, searching multiple proteins is not possible, requiring extensive manual curation. DomainViz automates the simultaneous identification of domains from multiple proteins and provides both consolidated and consensus outputs for further analysis and publication. This is highlighted by the production of a ‘consensus’ histogram plot that depicts the distribution and positionality of domains within a representative median protein sequence derived from the input protein sequences. - -### General Operations -File Upload: DomainViz accepts a single multiple sequence fasta file. The file extension should be .FA or .FASTA and the file size should be less than 10 Mb. Each sequence present within the fasta file should be formatted as follows: - ->AT3G19040.1|PACid:19663337_AtTAFIIb -MICRVDYGSNDEEYDGPELQVVTEEDHLLPKREYLSSEIAESRR -YREVIRSEREEEKRRKAKQKKKLQRGILENYPPRRNDGISSESGQNINSLCVSDFERNRTEYAPQPKRRKKGQVGLANILESIVDTLRVKEVNVSYLFLK -PVTKKEAPNYLEIVKCPMDLSTIRDKVRRMEYRDRQQFRHDVWQIKFNAHLYNDGRNLSIPPLADELLVKCDRLLDEYRDELKEAEKGIVDSSDSLR* - -The chevron denotes the header line containing unique identifying information, which is ended by a line return to denote this as a separate entity from the sequence. At the end of each sequence should be a (*) to ensure the end of the sequence is denoted. Sequences of 16 amino acids or less, and greater than 10005000 amino acids are not compatible with DomainViz. - -#### NOTE: Ensure that headers and sequences are not duplicated in the file and that standard amino acid code is used. Accepted characters are GALMFWKQESPVICYHRNDTX, in upper or lower case. - -### Submit Task and Analysis: -Once a file is successfully uploaded, use the Submit Task button to start the analysis. This will redirect to a new results page with an unique identifying 32 digit Result ID. Please copy and save the Result ID. You can use this ID to retrieve results for a period of 7 days post analysis. Please note that some searches can take a long time, from several minutes to hours and you can check the status of your analysis using your Result ID. -#### Example Result ID: 5ff3eeda_5842_5879_d627_f4d1faea3c84 - -Without a Result ID , the data will not be retrievable and the analysis will need to be re-run. If an error occurs, please follow the directions in the pop-up box that results. - -### Data Retrieval: -To retrieve a previous analysis, enter the Result ID into the “Result ID” text box on the DomainViz homepage . Analyses are retained for a total of 7 days prior to automatic deletion. - -### Load Example: -This option will automatically load a .fa or .fasta file to produce an example analysis visualization as well as an example downloadable output. - -## Settings -### Absolute Results: -Absolute results means that we will plot absolute numbers on y axis of plots instead of relative ones. If the box is unchecked, we plot relative results, if it is checked, we plot absolute results. - -### Minimum Domain Prevalence: -Only domains occuring in a ratio higher than the number are plotted will be present in the visualized and compiled output (e.g. If the value is 0.5, the domain has to occur somewhere in the protein of at least 50% of sequences). - -### Minimum domain position conservation: -Only domains occuring at a ratio higher than this number at a specific place in the protein group will be presented in the output (e.g. if value is 0.5, 50% of the sequences have to have this domain at the same relative position). - -### Scale: -The number input here represents the number of inches per 100 amino acids that the plot will use to display each visualization. - - -## Data Interpretation - -The histograms depict both the position and prevalence of eachspecific protein domains (identified from the Pfam and Prosite databases) within the group of proteins input by the user. - -Generally, results with non-overlapping domains can be directly interpreted as showing the prevalence and position of each domain with different degrees of conservation within the protein group. - -If the visualization of a group of proteins shows two overlapping domains (e.g. A and B), at for example each with 50% 0.5 prevalence, then there are three possible explanations:ways how the figure could have been compiled in this way. - -#### Case 1: A subset of proteins have no domain predicted, while the remaining subset of proteins have both domains A and B predicted at the same spot. (In this case, the subsets are each half of the total set of proteins). - -#### Case 2: A subset of proteins have domain A predicted, and the possess an other subset of proteins have domain B predicted. (In this case, the subsets are each half of the total set of proteins. - -#### Case 3: Any combination of Case 1 and Case 2 leading to the same prevalence ratios. Only further investigation of the results available in the download option can discriminate the case. - -### Downloadable DomainViz Outputs -The DomainViz output is available for download as a .zip file containing multiple files types. This includes: Job.id.tsv files containing the raw output data from Pfam and Prosite. Job.id_ProteinGroup.csv allows users to replot the data used in creating each visualized histogram. Lastly, Job.id_ProteinGroup.pdf files that are high resolution vector files that can be used for further manipulation and/or publication. - -## FAQ -1. Q. How do I retrieve my results after navigating away from the processing results? - A. Ensure that you retain the 32-character unique identifier result ID displayed on the Results page. EnterPlace this code into the Result ID field on the homemain page and hit “Go to My Results”. Alternatively, bookmark the Results page and revisit it after some time. - -2. Q. I have been warned that I have duplicate sequences in my FASTA file? - A. DomainViz will still process your file under the assumption that duplicate sequences refer to independent proteins that share the same sequence. We advise checking that spurious duplicate sequences were not accidentally introduced during input file creation as they can lead to altered results. run; however, it is recommended that these be removed before proceeding further. - -3. Q. What is the maximal number of protein sequences that can be analyzed at once? - A. DomainViz can currently assess 1000 protein sequences at once. NOTE: The more sequences in a single query the longer the analysis will take. - -4. Q. My fasta isn't uploading, it says there is a problem with one of my lines? How do I fix this? - A. Please remove the lines that are causing issues. \ No newline at end of file diff --git a/website-glen/README.md b/website-glen/README_REACT.md similarity index 100% rename from website-glen/README.md rename to website-glen/README_REACT.md diff --git a/website-glen/deployment/README.md b/website-glen/deployment/README.md new file mode 100644 index 000000000..1c1eb17a2 --- /dev/null +++ b/website-glen/deployment/README.md @@ -0,0 +1,143 @@ +# Intro to the site +Hello! If you are reading this, you are probably trying to deploy, redeploy, or fix the Uhrig Lab DomainViz website. Thanks! + +The way this site is organized is rather standard, however, I (Cameron Ridderikhoff) haven't fully separated the REST API/backend from the frontend. + +The frontend is contained mainly within the `src` folder, but there are some important files contained within the `public` folder as well, namely `index.html`, `example_iframe.html` and `favicon.ico`. You can find these folders at the path: `Glen Website/website-glen/src` and `Glen Website/website-glen/public` respectively. + +The api is contained in a folder aptly named: `api`. You can find this in the path: `Glen Website/website-glen/api`, however, this folder is mainly for Flask environment variables, and for Flask's wsgi.py file, which is the entrypoint for the backend's service. This will be further explained in *Section 2 - Backend Deployment*. You can find the Python files that contain the API endpoints in the `api/api` subfolder. Feel free to rename this if you like, but you will have to change the service files. + + +# Section 1 - Frontend Deployment +## Section 1.1 Redeploy - Frontend +The frontend deployment is quite easy, at least if you are redeploying the site, and not making too many major changes. There is a file within this folder `Glen Website/website-glen/deployment/redeploy.sh` that will automatically redeploy both the frontend and backend. However, this shell file isn't ideal, and could certainly use some updating (There is a TODO in the file if you want some more work). + +This file needs to be run with `sudo`, so the full commands from logging onto the server should be: +### 1.1.1 IMPORTANT +```bash +$cd Website_Glen/website-glen/deployment +$sudo ./redeploy.sh +``` + +You may have to deal with npm (it has certainly been a struggle for me), and I find the best way to fix issues I am having with npm is to delete the `node_modules` folder and `package-lock.json` files, and then run `redeploy.sh`, which runs `npm install` to refresh your packages. This usually fixes enough npm package conflicts to allow the `redeploy.sh` to run to completition. + +## Section 1.2 Fresh Deploy - Frontend +This guide only works for Linux distributions. If you have another OS that you are trying to serve this site from, you can loosely follow these instructions, but many may not work, or may have incorrect file paths. + +If you run in the situation that Glen, or others, ask you to deploy the site onto a fresh Cirrus instance, or other cloud infrastructure (Azure/AWS/GCP, etc...) then you will need to do a bit more work. I have tried to list all of the steps below, but I may miss something, so stay sharp! (Note: you will also have to install the backend - see *Section 2.2 Fresh Deploy - Backend*) +1. Clone the repo +2. Install node and npm +3. Run `sudo npm install` in the `Website_Glen/website_glen` directory to ensure npm has correctly installed. +4. Create a SSL certificate using [certbot](https://certbot.eff.org/) NOTE: We are running `Nginx` on whatever Ubuntu/Linux distro you are using. +5. Ensure that the file paths of the certificate match those of the frontend service file (`Website_Glen/website-glen/deployment/prodoplot.nginx`): +```bash +$ssl_certificate /etc/letsencrypt/live/uhriglabdev.biology.ualberta.ca/fullchain.pem; +$ssl_certificate_key /etc/letsencrypt/live/uhriglabdev.biology.ualberta.ca/privkey.pem; +``` +If they are not, either change the filepaths, or lines 8 and 9 of the frontend service file. +6. Copy the frontend service file into the `/etc/nginx/sites-available/` folder +```bash +$sudo cp Website_Glen/website-glen/deployment/prodoplot.nginx /etc/nginx/sites-available/prodoplot.nginx +``` +7. Create a soft-link from the sites-available folder to sites-enabled: +```bash +$sudo ln /etc/nginx/sites-available/prodoplot.nginx /etc/nginx/sites-enabled/prodoplot.nginx +``` +8. Reload Nginx: +```bash +$sudo systemctl reload nginx +``` + +With all of this done, you should have a working frontend, that you can view in your web browser. + +**RESOURCES** +Here are some of the videos/blogs that I used to learn how to deploy an Nginx site: +1. [How to Deploy a React + Flask App](https://blog.miguelgrinberg.com/post/how-to-deploy-a-react--flask-project) +2. [How to run Flask App on HTTPS](https://blog.miguelgrinberg.com/post/running-your-flask-application-over-https) + + +# Section 2 - Backend Deployment +The backend is slightly more complex, but certainly manageable. It is quite easy to redeploy, but rather difficult to deploy fresh. + +## Section 2.1 Redeploy - Backend +The backend deployment is quite easy, at least if you are redeploying the site, and not making too many major changes, much like the frontend. There is a file within this folder `Glen Website/website-glen/deployment/redeploy.sh` that will automatically redeploy both the frontend and backend. (See *Section 1.1 Redeploy - Frontend* for more details) + +This file needs to be run with `sudo`, so the full commands from logging onto the server should be: +### 2.1.1 IMPORTANT +```bash +$cd Website_Glen/website-glen/deployment +$sudo ./redeploy.sh +``` + +Luckily python is nicer than npm, so usually modules aren't as big of an issue. However, if you run into any issues, install all packages inside the virtual environment by traveling to the first api folder and activate the virtual environment and install packages: +```bash +$cd Website_Glen/website-glen/api/ +$source venv/bin/activate +$pip3 install -r requirements.flask.txt +``` +Then navigate to the second api folder and activate the virtual environment and install packages: +```bash +$cd Website_Glen/website-glen/api/api/ +$source propplotenv/bin/activate +$pip3 install -r requirements.domainviz.txt +``` + +If you add more packages to the backend, add them to `requirements.flask.txt`. + +## Section 2.2 Fresh Deploy - Backend +This guide only works for Linux distributions. If you have another OS that you are trying to serve this site from, you can loosely follow these instructions, but many may not work, or may have incorrect file paths. + +The same applies for backend as for frontend. +1. Clone the repo +2. Install python3.8 [Downloads Page](https://www.python.org/downloads/release/python-3811/) +3. Install python3 virtual environment +```bash +$sudo python3 -m pip install --user virtualenv +``` +4. Create a virtual environment for the backend in the `Website_Glen/website-glen/api/` directory: +```bash +$sudo python3 -m venv venv +``` +5. Activate the virtual environment: +```bash +$source venv/bin/activate +``` +6. Deactivate the environment: +```bash +$deactivate +``` +7. Install packages: +```bash +$pip install -r requirements.flask.txt +``` +8. Create a virtual environment for domainviz.py in the `Website_Glen/website-glen/api/api/` directory: +```bash +$sudo python3 -m venv protplotenv +``` +9. Activate the virtual environment: +```bash +$source venv/bin/activate +``` +10. Install packages: +```bash +$pip install -r requirements.domainviz.txt +``` +11. Deactivate the environment: +```bash +$deactivate +``` +12. Copy the backend service file from the `Website_Glen/website_glen/deployment` folder into the `/etc/systemd/system/` folder: +```bash +$sudo cp prodoplot.service /etc/systemd/system/prodoplot.service +``` +13. Run the service: +```bash +$sudo systemctl daemon-reload +$sudo systemctl start prodoplot.service +``` + +With all of this done, you should have a working backend, and you can check that it is running by running the command: +```bash +$sudo systemctl status prodoplot +``` +It should say "active (running)" in green text, and have a green dot by the `prodoplot.service` name. Press `CTL+C` to exit. \ No newline at end of file diff --git a/website-glen/deployment/redeploy.sh b/website-glen/deployment/redeploy.sh index 8361c15de..946f3b2a3 100755 --- a/website-glen/deployment/redeploy.sh +++ b/website-glen/deployment/redeploy.sh @@ -1,3 +1,7 @@ +# TODO: The IFS and following for loop should be able to display the information of the currently running jobs, +# and then you should be able to kill those jobs before closing the service files with `systemctl restart prodoplot`. +# The goal there is to be able to re-run the jobs using a direct python3 call to the domainviz.py file, thus not losing any +# data for users upon redeployment. #!/bin/sh NUM_INSTANCES=$(ps -ef | grep "python" | egrep -v "grep|vi|more|pg" | wc -l) if [ $NUM_INSTANCES -gt 0 ]; diff --git a/website-glen/public/index.html b/website-glen/public/index.html index 49861dfbd..9c10c5899 100644 --- a/website-glen/public/index.html +++ b/website-glen/public/index.html @@ -14,6 +14,7 @@ user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/ --> + diff --git a/website-glen/src/App.js b/website-glen/src/App.js index 0dc53a906..bd9f43db0 100644 --- a/website-glen/src/App.js +++ b/website-glen/src/App.js @@ -2,7 +2,17 @@ import React from 'react'; import './App.css'; import 'fontsource-roboto'; import { makeStyles } from '@material-ui/core/styles'; -import { AppBar, Toolbar, Typography, Button, createMuiTheme, ThemeProvider, Divider, Box, Container } from '@material-ui/core'; +import { + AppBar, + Toolbar, + Typography, + Button, + createMuiTheme, + ThemeProvider, + Divider, + Box, + Container +} from '@material-ui/core'; import { BrowserRouter, Switch, @@ -19,8 +29,16 @@ import { Help } from './components/Help'; import { TermsOfUse } from './components/TermsOfUse'; import { PrivacyStatement } from './components/PrivacyStatement'; import DomainViz from './components/DomainViz'; +/* MotifX was the previous name of UMotif. When using this module, have a look at the UMotifMerge branch + * and attempt to merge that into the main codebase. https://github.com/UhrigLab/DomainViz/tree/UMotifMerge + * That way, that work is not lost. + */ // import MotifX from './components/MotifX'; + +/* This makeStyles() is used to bring the Raleway font into the DomainViz site, + * as well as for certain typeographys used on the toolbar. + */ const useStyles = makeStyles((theme) => ({ app: { minHeight: '85.8vh', @@ -62,10 +80,10 @@ const useStyles = makeStyles((theme) => ({ const theme = createMuiTheme({ palette: { primary: { + // This is grey as hex. main: '#e8e8e8', }, secondary: { - // This is green.A700 as hex. main: '#000000', }, }, @@ -92,8 +110,13 @@ function App() { Protein tools - {/* Need this for spacing for now */} + {/* Need this for spacing - If you are better at frontend than me, please change it */} + + {/* The Home button is currently disabled, as is the MotifX/UMotif button. This is so that + * users are automatically redirected to the DomainViz page, since there is only one tool enabled at the moment. + * When UMotif is added, you should enable the Home button, and un-comment the Home.js component to create a real home page. + */} {/* */} diff --git a/website-glen/src/README.md b/website-glen/src/README.md new file mode 100644 index 000000000..dbaace40e --- /dev/null +++ b/website-glen/src/README.md @@ -0,0 +1,23 @@ +# Cameron's Style Guide +This guide is to be used to understand how I styled my ReactJS components. The short answer is "poorly". This was the first website I created, and as such, the styling leaves much to be desired. + +Each page is set up using the material-ui `` component. The Grid is setup in rows, and every `{12}` xs points is equal to one row with the spacing that I used. + +For example, `` is one row, or, +```html + + + + +``` +is also one single row. + +Sometimes there are empty `` objects, these are used to create empty space +Every 12 xs points are separated from the next with a blank line. + +# Cameron's Component Guide +All components are functional components. Look up a React functional components guide if you need help. + +For some reason, some of my components are set up as `function xyz() {}` and others as `const xyz = () => {}`. This is likely caused by me looking at different coding practices, and not realizing what the difference between the two are, or why one would choose either. This should be changed, for consistency. + +As well, some components use a tab spacing of 2 spaces, and others use a spacing of 4 spaces. I'm honestly not sure when this happened, but by the time I noticed it, it would have been too much work to rectify, so I left it as is. \ No newline at end of file diff --git a/website-glen/src/components/About.js b/website-glen/src/components/About.js index 47b08175a..805bcc868 100644 --- a/website-glen/src/components/About.js +++ b/website-glen/src/components/About.js @@ -4,7 +4,6 @@ import { makeStyles } from '@material-ui/core/styles'; import { Link as RouterLink } from 'react-router-dom'; - const useStyles = makeStyles((theme) => ({ paper: { padding: theme.spacing(2), @@ -21,7 +20,20 @@ const useStyles = makeStyles((theme) => ({ height: '580px', }, })); + + export const About = () => { + /* This functional component displays information about the site, and about our organization. + * A rather simple component, and very similar to Help.js, PrivacyStatement.js, and TermsOfUse.js. + * + * One complexity of this component is the use of RouterLink vs. Link. While both components are called Link in their respective + * libraries, I have renamed the react-router Link to , which is a component that allows the user to navigate around + * our site, whereas the component from material-ui is an external link to another site. + * + * Based on this Google Doc: https://docs.google.com/document/d/1bflUShOzD8q-_b0dgBLxk6FaLmpfTEnRkgwMIOGcaxQ/edit + * + * This component could be improved by using css, and changing from a Grid layout to a more flexible one. + */ const classes = useStyles() return ( @@ -31,6 +43,7 @@ export const About = () => { The + {/* Inline allows us to have a differently styled piece of text on the same line as text */} Uhrig Lab at the University of Alberta is a protein biochemistry and proteomics research group interested in protein function discovery. We are also currently developing multiple open-source, accessible, and easy to use protein sequence analysis tools to enable biological discovery. @@ -49,4 +62,3 @@ export const About = () => { ); } - diff --git a/website-glen/src/components/AccordionSetup.js b/website-glen/src/components/AccordionSetup.js index 564e22b82..99091174a 100644 --- a/website-glen/src/components/AccordionSetup.js +++ b/website-glen/src/components/AccordionSetup.js @@ -6,6 +6,7 @@ import AccordionDetails from '@material-ui/core/AccordionDetails'; import Typography from '@material-ui/core/Typography'; import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; + const useStyles = makeStyles((theme) => ({ root: { width: '100%', @@ -16,7 +17,14 @@ const useStyles = makeStyles((theme) => ({ }, })); + function AccordionSetup({ id, header, body }) { + /* This functional component is an accordian, combined with accordion details. It's useful + * since one only has to pass in an id, header and body, and a full accordion is returned. + * + * Useful for saving lines of code, which is the biggest benefit of reusable components. + * It could be improved by adding a parameter for the header and body typography settings. + */ const classes = useStyles(); return ( @@ -38,5 +46,4 @@ function AccordionSetup({ id, header, body }) { ); } - export default AccordionSetup; diff --git a/website-glen/src/components/DomainViz.js b/website-glen/src/components/DomainViz.js index 9d06d9563..01a3f1a68 100644 --- a/website-glen/src/components/DomainViz.js +++ b/website-glen/src/components/DomainViz.js @@ -1,5 +1,5 @@ import React, { useState } from 'react'; -//import request from 'utils/Request'; TODO refactor to remove burden from ProtPlot.js +//import request from 'utils/Request'; TODO refactor DomainViz to remove burden from the component, since it already does too much import axios from 'axios'; import UploadFile from './utils/UploadFile'; import AccordionSetup from './AccordionSetup'; @@ -14,6 +14,7 @@ import { useHistory } from 'react-router'; import DomainVizIcon from './img/domainviz.png'; import { saveAs } from 'file-saver'; + const useStyles = makeStyles((theme) => ({ root: { flexGrow: 1, @@ -37,6 +38,7 @@ const useStyles = makeStyles((theme) => ({ }, })); + //generates random id; let guid = () => { let s4 = () => { @@ -48,8 +50,14 @@ let guid = () => { return s4() + s4() + '.' + s4() + '.' + s4() + '.' + s4() + '.' + s4() + s4() + s4(); } + function ProtPlot() { - //temp for production + /* This functional component contains the logic, as well as the UI for the DomainViz page. This is the page that allows + * users to upload their fasta files, add their own settings, and produce the results. It also automatically redirects the user + * to the correct output page. + */ + + //TODO This was supposed to be temp for production, and the Home page was supposed to be added, but it hasn't been done yet. function getImages() { let id = textFields.uidTextField; if (!id) { @@ -73,12 +81,15 @@ function ProtPlot() { history.push('/view-results/' + textFields.uidTextField); } //end of temp + const classes = useStyles(); const resultID = guid(); const history = useHistory() + // Input files const [fastaFiles, setFastaFiles] = useState([]); + // User-defined parameters const [checkboxes, setCheckboxes] = useState({ absoluteResultsCheckbox: false, fastaFileLoadedCheckbox: false, @@ -87,7 +98,6 @@ function ProtPlot() { const handleCheckBox = (event) => { setCheckboxes({ ...checkboxes, [event.target.name]: event.target.checked }); }; - const [textFields, setTextFields] = useState({ cutoffTextField: '0.05', maxCutoffTextField: '0.05', @@ -102,6 +112,7 @@ function ProtPlot() { saveAs(response.url); }); } + function uploadTestFastaFile() { // This function sends dummy info to the backend, so that it knows which file to use setFastaFiles( @@ -109,6 +120,7 @@ function ProtPlot() { ) } function uploadMultipleTestFastaFiles() { + // This function sends dummy info to the backend, so that it knows which files to use setFastaFiles( [ {file: "mult_test_1", name: "multi_test_file_1.fa"}, @@ -130,8 +142,6 @@ function ProtPlot() { } } function changeFAFileName(index, newName) { - console.log(fastaFiles) - console.log(index) // If the fastafile is one of the example files, we only replace its name, otherwise, we replace the whole file // since that is the only way to change a File's name in Javascript. if (fastaFiles[index].file) { @@ -154,8 +164,11 @@ function ProtPlot() { ]); } } - async function handleFastaFiles(fileList) { + async function handleFastaFiles(fileList) { + /* This function is run when the user uploads one or more fasta files, it validates the files + * and stores them in the fastaFile State variable to send them to the backend. + */ // Check that there are no test files in the fastaFiles list, since the backend cannot currently handle both test and regular files for (let i=0; i { - console.log(response); + // Reset setting values textFields.scaleFigureTextField = ''; textFields.maxCutoffTextField = ''; textFields.cutoffTextField = ''; @@ -288,6 +305,7 @@ function ProtPlot() { DomainViz logo + Protein domain search {'&'} visualization tool @@ -371,7 +389,7 @@ function ProtPlot() { - {/* temp for production */} + {/* temp for production - should be added to Home component long-term. */} diff --git a/website-glen/src/components/Footer.js b/website-glen/src/components/Footer.js index c5f0c5ab3..d9b9c9a7f 100644 --- a/website-glen/src/components/Footer.js +++ b/website-glen/src/components/Footer.js @@ -32,34 +32,41 @@ const useStyles = makeStyles((theme) => ({ }, })); + function Footer () { - const classes = useStyles(); - return ( - - - - {"University - - - - - Terms of Use - - - Privacy Statement - - - - - Contact: - - protools@ualberta.ca - - {'\u00A9'} 2020 The Uhrig Lab - - + /* This function is the footer for each page, and is incredibly poorly styled, however + * it works for all current pages. + * It contains links to important pages, and an email link. + */ + const classes = useStyles(); + return ( + + + + + {"University + + + + + Terms of Use + + + Privacy Statement + - + + + Contact: + + protools@ualberta.ca + + {'\u00A9'} 2020 The Uhrig Lab + + + + ); } export default Footer; + diff --git a/website-glen/src/components/Help.js b/website-glen/src/components/Help.js index 10208318d..bf6c66e5b 100644 --- a/website-glen/src/components/Help.js +++ b/website-glen/src/components/Help.js @@ -25,7 +25,17 @@ const useStyles = makeStyles((theme) => ({ width: "1000px" }, })); + + export const Help = () => { + /* This functional component displays helpful information for a user who may be struggling to use the tool. + * A rather simple component, and very similar to About.js, PrivacyStatement.js, and TermsOfUse.js. + * + * Based on this Google Doc: https://docs.google.com/document/d/1degKXhefAYDrJlXRwpU-yPnqwVgvFfo67koMiitGrqg/edit#heading=h.b11zvzh3fvy0 + * + * This component could be improved by using css, and changing from a Grid layout to a more flexible one. + * Potentially it could be changed by only having one link to each unique URL, rather than many. + */ const classes = useStyles() return ( @@ -101,6 +111,7 @@ export const Help = () => { Snapshot: Users can click the Camera icon in the toolbar to take a .png snapshot of the current display in the plot (for example, after hiding a particular domain). + {/* This iframe is an example of our outputs, and will not appear unless the `example_iframe.html` file is in the `public` folder */}