This project was bootstrapped with Create React App.
Note that you must set PUBLIC_URL env var to the domain name this is hosted on. Dev example given here In the project directory, you can run:
Runs the app in the development mode.
Open http://localhost:3000 to view it in your browser.
The page will reload when you make changes.
You may also see any lint errors in the console.
Launches the test runner in the interactive watch mode.
See the section about running tests for more information.
You need to set environment variable PUBLIC_URL=''
Typical values can be: Dev: '' Staging : http://bioinf.cs.ucl.ac.uk/psipred_beta Production : bioinf.cs.ucl.ac.uk
Builds the app for production to the build
folder.
It correctly bundles React in production mode and optimizes the build for the best performance.
The build is minified and the filenames include the hashes.
Your app is ready to be deployed!
See the section about deployment for more information.
We're using esbuild. Esbuild does not natively handle sass. I can't for the life of me get the esbuild sass plugin to work so... I just wrote a quick sass converter for the molstart scss files. Run it with
node sass_converter.js > public/static/css/light.css
Then we can just load it in the HTML header etc...
React has a heirarchical model of the page and page regions. Sibling regions of the page can share state by storing that state in a parental node.
You can learn more in the Create React App documentation.
To learn React, check out the React documentation.
The usual react model is for single page single-entry point dynamic pages. Here we have adapted this to a multi entry point site so that all code runs user side (unlike old psipred_javascript, which dispatched some things to the backend).
There are three entry points; interface
, msa
and model
. Interface is the user interface that users use to select jobs. msa is an entry point for displaying sequence alignments and model is an entry point that requests and shows 3D models (based off an alignment.)
And we have a shared folder that lets us share code between models
The model index.js
is now just a dispatcher for the 3 entry points and holds any global state that all three entry points need.
The Parent container for the page/results is called Interface
and can be found in the index.js. This is really just the menu, header and footer regions. The main action happens in it's immediate child; PsipredSite
. From here its child is DisplayArea
. DisplayArea
is responsible for holding most of the state of the pages and it's children are MainForm
, Sidebar
, ResultsMain
, ResultsSidebarTimes
, ResultsSidebarDownloads
and ResultsSidebarResubmission
.
This is just a simple class that reads the alignment and annotation files it needs and uses nightingale to display that alignments
This is just a simple class that reads the alignment files it needs, dispatches a request for a 3D model and displays that when it comes back.
See also class_layout.odp
- PsipredSite (psipred_site.js): Outer container for whole page with URI initialisation
- DisplayArea (psipred_site.js): Main container for the app that has all the shared the application state variables
- MainForm (MainForm.js): Small class that wraps the interactive parts of the form
- FormInteractivity (MainForm.js): Small class that warps the form selector
- SeqForm (MainForm.js): Main form that the user can use to select methods and submit Seq data
- StructForm (MainForm.js): Main form that the user can use to select methods and submit Structural data
- FormInteractivity (MainForm.js): Small class that warps the form selector
- Sidebar (sidebar.js): Class shows the sidebar with advanced options
- ResultsMain (results.js): Class is called after data submission and handles submitting a job and then displaying the results
- ResultsSequence (results_sequence.js): Class handles getting the results files for a sequence job and displaying them
- ResultsStructure (results_strucutre.js): TO BE IMPLEMENTED
- ResultsSidebarTimes (results_sidebar_times.js): Small class handles getting the RunTimes and displaying them while the user waits
- ResultsSidebarDownloads (results_sidebar_downloads.js): This class handles showing the download files panel and bundling files in to a zip for the users
- ResultsSidebarResubmission (results_sidebar_resubmission.js): This shows the resubmission panel on the results page and handles submitting a new job
- MainForm (MainForm.js): Small class that wraps the interactive parts of the form
- DisplayArea (psipred_site.js): Main container for the app that has all the shared the application state variables
-
First modify the page in
interface/psipred_site.js
inclass DisplayArea
. Add any new state variables for (sidebar items) to the constructorthis.state
(line 35) if you think you'll need them. Mostly it'll be things for any advanced config but you should usually be fine with what is already there. You will also need to update thehandleReset
andhandleResubmit
functions to reinitialise any of these new state variables. Add your job names toseq_job_names
orstruct_job_names
. If your new job produces files types not covered by previous jobs then add file globs for your new job by updatingresults_map
inthis.state
in theDisplayArea
class. This is critical for setting which files show up in the downloads area.analyses
inthis.state
controls which jobs already have a check mark in the form on page load.job_strings
keeps a track of how your new method is spelt across the site. Must be of the form'[ALGORITHM]_job'
and must match what the job is called over the backend API. -
In
mainform.js
add the algorithm to HTML table in either theSeqForm
orStructForm
class. Copy an existing check box and edit as needed. Both the inputname
andvalue
must be of the form'[ALGORITHM]_job'
and must match what the job is called over the backend API. EnsureonChange
andchecked
are correct. -
If it is a new sequence job, don't forget to add your job to the
ResultsSidebarResubmission
class inresults_sidebar_resubmission.js
and don't forget any tooltips. Copy an existing entry and edit as needed. -
If you need extended sidebar options edit
sidebar.js
. Update theSidebar
class to include any additional panels when it detects if'[ALGORITHM]_job'
has been selected. And then reference a new class of the form[Algorithm]Options
. Add your new class and the appropriate inputs. You MUST ensure that the form input names match the new state variable names you added in step 1 if you added new state variables (i.e.DisplayArea
'sthis.state
etc...). You will also have to updateshared/index.js
configurepost()
to include extra options. Important incheckform.js
add any checks for params the user provides invalidateFormData
-
In
checkform.js
invalidateFormData()
. Add/Update any new validations you now may have for the new/advanced/options inputs. -
In
results.js
updatethis.state
with the waiting messages for your job. -
In
results_sidebar_times.js
in theResultsSiderbarTimes
class add an if inrender
for the runtime of your new job type. -
If you haven't configured the job in the backend A_A instance I find now is a good time to do that
-
If we're handling a seq result: a) in
results_sequence.js
in theResultsSequence
class update the constructor andthis.state
to handle any results and plots you need, usingReact.createRef()
to bind new page elements you need. b) Inrender()
add an appropriate new chunk to hold any results panel for this job (i.e. likethis.props.analyses.includes("psipred_job")
). UserenderPanel()
to insert an area for a diagram c) IngetResults()
ensureif(data.state === "Complete"){
handles parsing any files that need it. Ensurethis.setState({
sends the results contents to an appropriate state variables to hold them here. d) IncomponentDidUpdate
update how you're handling any arrived results files. For the plots or tables in the lower page region e) updateresults_sidebar_downloads
to ensure the files you want users to access are available. and updatereturnzip()
appropriately. Recall that you need to add the results file glob to the list ofresults_map
list inpsipred_site.js
-
If we're handling a struct result: a) If we're working on structure methods you can set the struct form in
psipredsite.js
, setformSelectedOption
toStructForm
b) now repeat what is in 9 but withresults_structure.js
If you added a new file type is step 1, then you have to update the staging and production apache config to serve that file type, see the ansible scripts/files
Now and again we have to take the server offline. You can add messages and suspensions by editing the appropriate variables in psipred_site.js
in the PsipredSite
class. suspension_message
will add a message to the top and the bottom of the page and remove the submit button on the form. server_message
will add a message to the top of the page. toggle these to null
to not display such a message.
-
ensure memembed and mempack work (need to use staging to debug as won't compile)
-
Set polling time correctly in
results_sequence.js
andresults_structure.js
-
in model/index.js there is a correct use of fetch with async/await to synchronously make a request. Should replace all httprequest uses with this pattern.
-
Maybe there is a way to dry out some of the createElement creation stuff in
results_sequence.js
andresults_structure.js
, especially for the img tag stuff. -
Change all parsers to correctly be JSX and/or new react classes.