Skip to content

Commit

Permalink
Session management (xchem#118)
Browse files Browse the repository at this point in the history
* Update: Session Management (#34)
- browser bomb to warn of unsupported nature
- add report error button to modal in case of no target available
- add logos to header
- set creation date as default title
- rename session saving buttons and change saving modal text

* Funders page (#35)

* New feature: Sessions page (#36)

* Fix testing for sessions (#37)
- Modify sessionList to remove scene information
- Update tests for new variables
- Reformat session summary on landing and session pages
- Add throbber during session loading

* bundle of fixes (#38)

* Mock up of proposal management (#39)

* Session debugging (#40)

* New feature: session renaming and deleting. closes xchem#109, closes #42 (#41)

* Bug fix: Select all compounds to the buy list. Closes xchem#106 (#42)

* Bug fix: stop multi-session generation, correctly update state and vector presentation. Closes xchem#112 & closes xchem#108 (#43)
- Compound classes transferred into fragglebox.
- Session generation refactored to stop generation of multiple sessions.
- Correct update of session title in header/modal/sessionList page.
- Redeploy vectors in NGL viewer.
- Compound list correctly displayed in fragglebox.

* Finalise sessions (#48)
- Add copy link button
- Check target access for fragglebox
- Deploy unrecognised target modal if necessary
- Fix associated bugs!

* Download pdb files (#49)
- enable users to download all pdbs for a target
- fix browser bomb for chrome 71
  • Loading branch information
ricgillams authored Dec 10, 2018
1 parent 81595e1 commit e840897
Show file tree
Hide file tree
Showing 35 changed files with 1,190 additions and 440 deletions.
5 changes: 5 additions & 0 deletions js/actions/actonTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export const SET_WATER = 'SET_WATER';
export const SET_HYDROGEN = 'SET_HYDROGEN';
export const SET_STAGE_COLOR = 'SET_STAGE_COLOR';
export const SET_NGL_PROT_STYLE = 'SET_NGL_PROT_STYLE';
export const REDEPLOY_VECTORS = 'REDEPLOY_VECTORS';
// Target, Site, Molecule, Protein, Compound
export const LOAD_TARGETS = 'LOAD_TARGETS';
export const LOAD_PROTEINS = 'LOAD_PROTEINS';
Expand Down Expand Up @@ -77,10 +78,14 @@ export const SET_CURRENT_COMPOUND_CLASS = 'SET_CURRENT_COMPOUND_CLASS';
export const RELOAD_SELECTION_STATE = 'RELOAD_SELECTION_STATE';
export const RELOAD_API_STATE = 'RELOAD_API_STATE';
export const SET_SAVING_STATE = 'SET_SAVING_STATE';
export const SET_SESH_LIST_SAVING = 'SET_SESH_LIST_SAVING';
export const SET_LATEST_SESSION = 'SET_LATEST_SESSION';
export const SET_LATEST_SNAPSHOT = 'SET_LATEST_SNAPSHOT';
export const SET_SESSION_ID = 'SET_SESSION_ID';
export const SET_ERROR_MESSAGE = 'SET_ERROR_MESSAGE';
export const SET_TARGET_UNRECOGNISED = 'SET_TARGET_UNRECOGNISED';
export const SET_BOND_COLOR_MAP = 'SET_BOND_COLOR_MAP';
export const SET_SESSION_ID_LIST = 'SET_SESSION_ID_LIST';
export const UPDATE_SESSION_ID_LIST = 'UPDATE_SESSION_ID_LIST';
export const SET_USER_ID = 'SET_USER_ID';
export const SET_SESSION_TITLE = 'SET_SESSION_TITLE';
50 changes: 44 additions & 6 deletions js/actions/apiActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,19 @@ import {
SET_DUCK_YANK_DATA,
RELOAD_API_STATE,
SET_SAVING_STATE,
SET_LATEST_SESSION,
SET_SESH_LIST_SAVING,
SET_LATEST_SNAPSHOT,
SET_LATEST_SESSION,
SET_SESSION_TITLE,
SET_SESSION_ID,
SET_SESSION_ID_LIST,
UPDATE_SESSION_ID_LIST,
SET_ERROR_MESSAGE,
SET_TARGET_UNRECOGNISED,
SET_UUID,
SET_USER_ID,
} from "./actonTypes";
import * as actions from "./actonTypes";

export const loadTargets = function (project_id=undefined) {
console.log("ACTIONS: " + project_id);
Expand Down Expand Up @@ -209,6 +213,22 @@ export const setSavingState = function (savingState) {
};
}

export const setSeshListSaving = function (seshListSaving) {
console.log("ACTIONS: setting saving state to " + seshListSaving);
return {
type: SET_SESH_LIST_SAVING,
seshListSaving: seshListSaving
};
}

export const setLatestSnapshot = function (uuid) {
console.log("ACTIONS: latest state snapshot is " + uuid)
return {
type: SET_LATEST_SNAPSHOT,
latestSnapshot: uuid
}
}

export const setLatestSession = function (uuid) {
console.log("ACTIONS: latest session uuid is " + uuid)
return {
Expand All @@ -217,11 +237,11 @@ export const setLatestSession = function (uuid) {
}
}

export const setLatestSnapshot = function (uuid) {
console.log("ACTIONS: latest state snapshot is " + uuid)
export const setSessionTitle = function (sessionTitle) {
console.log("ACTIONS: set session title to " + sessionTitle)
return {
type: SET_LATEST_SNAPSHOT,
latestSnapshot: uuid
type: SET_SESSION_TITLE,
sessionTitle: sessionTitle
}
}

Expand All @@ -241,6 +261,14 @@ export const setSessionIdList = function (input_json) {
};
}

export const updateSessionIdList = function (input_json) {
console.log("ACTIONS: sessionList summary written to state");
return {
type: UPDATE_SESSION_ID_LIST,
sessionIdList: input_json,
};
}

export const setErrorMessage = function (errorMessage) {
console.log("ACTIONS: errorMessage is " + errorMessage)
return {
Expand Down Expand Up @@ -279,12 +307,22 @@ export const reloadApiState = function (apiReducers) {
type: RELOAD_API_STATE,
target_on_name: apiReducers.target_on_name,
target_on: apiReducers.target_on,
target_id: apiReducers.target_id,
molecule_list: apiReducers.molecule_list,
mol_group_list: apiReducers.mol_group_list,
mol_group_on: apiReducers.mol_group_on,
hotspot_list: apiReducers.hotspot_list,
hotspot_on: apiReducers.hotspot_on,
app_on: apiReducers.app_on
app_on: apiReducers.app_on,
sessionIdList: apiReducers.sessionIdList,
latestSession: apiReducers.latestSession,
project_id: apiReducers.project_id,
group_id: apiReducers.group_id,
group_type: apiReducers.group_type,
pandda_event_on: apiReducers.pandda_event_on,
pandda_site_on: apiReducers.pandda_site_on,
pandda_event_list: apiReducers.pandda_event_list,
pandda_site_list: apiReducers.pandda_site_list,
}
}

Expand Down
11 changes: 10 additions & 1 deletion js/actions/nglLoadActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import {
SET_NGL_ORIENTATION,
SET_LOADING_STATE,
SET_STAGE_COLOR,
SET_NGL_PROT_STYLE
SET_NGL_PROT_STYLE,
REDEPLOY_VECTORS,
} from "./actonTypes";


Expand Down Expand Up @@ -128,3 +129,11 @@ export const setNglProtStyle = function (nglProtStyle) {
nglProtStyle: nglProtStyle
};
}

export const redeployVectors = function (objectsWereInView) {
console.log("ACTIONS: " + objectsWereInView);
return {
type: REDEPLOY_VECTORS,
objectsWereInView: objectsWereInView
}
}
8 changes: 4 additions & 4 deletions js/actions/selectionActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -195,10 +195,10 @@ export const setHighlighted = function (item){
}
}

export const reloadSelectionState = function (item){
console.log("RELOAD STATE: " + item)
export const reloadSelectionState = function (savedSelectionReducers){
console.log("RELOAD STATE: " + savedSelectionReducers)
return {
type: RELOAD_SELECTION_STATE,
item: item
savedSelectionReducers: savedSelectionReducers
}
}
}
2 changes: 1 addition & 1 deletion js/components/browserBombModal.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export class BrowserBomb extends React.Component {
if (typeof InstallTrigger !== 'undefined'){
this.setState(prevState => ({currentBrowser: "Firefox should be supported"}));
this.setState(prevState => ({notSupported: false}));
} else if (!!window.chrome && !!window.chrome.webstore){
} else if (!!window.chrome){
this.setState(prevState => ({currentBrowser: "Chrome should be supported"}))
this.setState(prevState => ({notSupported: false}));
} else {
Expand Down
36 changes: 21 additions & 15 deletions js/components/compoundList.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* Created by abradley on 15/03/2018.
*/
import { Row, Well, Button} from 'react-bootstrap';
import { Row, Well, Button, ButtonToolbar} from 'react-bootstrap';
import React from 'react';
import {connect} from "react-redux";
import CompoundView from "./compoundView";
Expand Down Expand Up @@ -46,15 +46,19 @@ class CompoundList extends React.Component {
}

selectAll() {
for(var key in this.props.this_vector_list) {
for (var index in this.props.this_vector_list[key]){
var thisObj = {
smiles: this.props.this_vector_list[key][index],
vector: key.split("_")[0],
mol: this.props.to_query,
class:parseInt(this.props.currentCompoundClass)
for(var key in this.props.thisVectorList) {
for (var index in this.props.thisVectorList[key]) {
if (index != "vector") {
for (var fUCompound in this.props.thisVectorList[key][index]) {
var thisObj = {
smiles: this.props.thisVectorList[key][index][fUCompound].end,
vector: this.props.thisVectorList[key].vector.split("_")[0],
mol: this.props.to_query,
class: parseInt(this.props.currentCompoundClass)
}
this.props.appendToBuyList(thisObj);
}
}
this.props.appendToBuyList(thisObj);
}
}
}
Expand Down Expand Up @@ -114,9 +118,9 @@ class CompoundList extends React.Component {
totArray.push(<input id="5" key="CLASS_5" style={{ width:100 }} defaultValue={this.state.compoundClasses[5]} onKeyDown={ this.handleClassNaming }></input>)
totArray.push(<p key={"breakdown"}><br/></p>)
var retArray = [];
for(var key in this.props.this_vector_list){
var vector_smi = this.props.this_vector_list[key]["vector"]
var change_list = this.props.this_vector_list[key]["addition"]
for(var key in this.props.thisVectorList){
var vector_smi = this.props.thisVectorList[key]["vector"]
var change_list = this.props.thisVectorList[key]["addition"]
for (var ele in change_list){
var data_transfer = change_list[ele]
var input_data = {}
Expand All @@ -133,8 +137,10 @@ class CompoundList extends React.Component {
totArray.push(<Row style={molStyle} key={"CMPD_ROW"}>{retArray}</Row>)
return <Well>
<h3><b>{this.props.querying ? "Loading...." : mol_string }</b></h3>
<Button bsSize="sm" bsStyle="success" onClick={this.selectAll}>Select All</Button>
<Button bsSize="sm" bsStyle="success" onClick={this.clearAll}>Clear Selection</Button>
<ButtonToolbar>
<Button bsSize="sm" bsStyle="success" onClick={this.selectAll}>Select All</Button>
<Button bsSize="sm" bsStyle="success" onClick={this.clearAll}>Clear Selection</Button>
</ButtonToolbar>
<div>{totArray}</div>
</Well>
}
Expand All @@ -146,7 +152,7 @@ class CompoundList extends React.Component {

function mapStateToProps(state) {
return {
this_vector_list: state.selectionReducers.present.this_vector_list,
thisVectorList: state.selectionReducers.present.this_vector_list,
to_query: state.selectionReducers.present.to_query,
compoundClasses: state.selectionReducers.present.compoundClasses,
currentCompoundClass: state.selectionReducers.present.currentCompoundClass,
Expand Down
61 changes: 61 additions & 0 deletions js/components/downloadPdb.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/**
* Created by ricGillams on 7/12/2018.
*/
import React from "react";
import JSZip from "jszip";
import {connect} from "react-redux";
import {Button, ButtonToolbar} from "react-bootstrap";
import fetch from "cross-fetch";
import FileSaver from "file-saver";

class DownloadPdb extends React.Component{
constructor(props) {
super(props);
this.handlePdbDownload = this.handlePdbDownload.bind(this);
}

async handlePdbDownload() {
var protPdbUrl = window.location.protocol + "//" + window.location.host + "/api/protpdb/?target_id=" + this.props.targetOn.toString();
var proteinsUrl = window.location.protocol + "//" + window.location.host + "/api/proteins/?target_id=" + this.props.targetOn.toString();
const protResponse = await fetch(proteinsUrl);
const protJson = await protResponse.json();
const protInfo = protJson.results;
const pdbResponse = await fetch(protPdbUrl);
const pdbJson = await pdbResponse.json();
const pdbInfo = pdbJson.results;
var zip = new JSZip();
const timeOptions = {year:'numeric', month:'short', day:'2-digit'}
var fName = this.props.targetOnName + "_allPdb_" + new Intl.DateTimeFormat('en-GB', timeOptions).format(Date.now()).replace(/\s/g, '-');
var totFolder = zip.folder(fName);
for(var structure in protInfo) {
var pdbData = pdbInfo[structure].pdb_data;
var pdbCode = protInfo[structure].code;
var molGroupUrl = window.location.protocol + "//" + window.location.host + "/api/molecules/?prot_id=" + pdbInfo[0].id;
const molResponse = await fetch(molGroupUrl);
const molJson = await molResponse.json();
const sdfData = molJson.results[0].sdf_info
totFolder.file(pdbCode+".pdb",pdbData);
totFolder.file(pdbCode+".sdf",sdfData);
}
const content = await zip.generateAsync({type: "blob"});
FileSaver.saveAs(content, fName + ".zip");
}

render() {
return <ButtonToolbar>
<Button bsSize="sm" bsStyle="success" onClick={this.handlePdbDownload}>Download all PBDs for target</Button>
</ButtonToolbar>
}
}

function mapStateToProps(state) {
return {
targetOn: state.apiReducers.present.target_on,
targetOnName: state.apiReducers.present.target_on_name,
}
}

const mapDispatchToProps = {
}

export default connect(mapStateToProps, mapDispatchToProps)(DownloadPdb);
15 changes: 12 additions & 3 deletions js/components/generalComponents.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ export class GenericList extends React.Component {
getUrl() {
// This should be defined by type
var base_url = window.location.protocol + "//" + window.location.host
if (DJANGO_CONTEXT["pk"] != undefined) {
var userId = DJANGO_CONTEXT["pk"].toString()
} else {
var userId = null;
}
// Set the version
base_url += "/api/"
var get_params = {}
Expand Down Expand Up @@ -86,13 +91,14 @@ export class GenericList extends React.Component {
}
}
else if (this.list_type == listTypes.SESSIONS) {
base_url += "viewscene/"
base_url += "viewscene/?user_id="+ userId
if (this.props.project_id != undefined) {
get_params.project_id = this.props.project_id
this.props.setSeshListSaving(true);
}
}
else {
console.log("DEFUALT")
console.log("DEFAULT")
}
var url = new URL(base_url)
Object.keys(get_params).forEach(key => url.searchParams.append(key, get_params[key]))
Expand All @@ -107,6 +113,7 @@ export class GenericList extends React.Component {
processResults(json) {
var results = json.results;
this.afterPush(results)
if (this.list_type == listTypes.SESSIONS && this.props.seshListSaving == true) {this.props.setSeshListSaving(false)}
return results;
}

Expand All @@ -119,7 +126,9 @@ export class GenericList extends React.Component {
response => response.json(),
error => console.log('An error occurred.', error)
)
.then(json => this.props.setObjectList(this.processResults(json)))
.then(
json => this.props.setObjectList(this.processResults(json))
)
}
this.old_url = url.toString();
}
Expand Down
Loading

0 comments on commit e840897

Please sign in to comment.