diff --git a/src/Routes.jsx b/src/Routes.jsx
index bd91454..2451e97 100644
--- a/src/Routes.jsx
+++ b/src/Routes.jsx
@@ -8,6 +8,7 @@ import Subtyping from './containers/Subtyping'
import Metadata from './containers/Metadata'
import Database from './containers/Database'
import Panseq from './containers/Panseq'
+import Search from './containers/Search'
// others
import Results from './containers/Results'
import VisibleResult from './containers/VisibleResult'
@@ -20,6 +21,7 @@ export const METADATA = dirpath + '/metadata'
export const DATABASE = dirpath + '/database'
export const PANSEQ = dirpath + '/panseq'
export const RESULTS = dirpath + '/results'
+export const SEARCH = dirpath + '/search'
export const VISIBLE_RESULT = dirpath + '/results/:hash'
const renderMergedProps = (component, ...rest) => {
@@ -45,6 +47,7 @@ const Routes = (token) => (
+
diff --git a/src/components/ResultSearch.js b/src/components/ResultSearch.js
index dc0246e..1b10736 100644
--- a/src/components/ResultSearch.js
+++ b/src/components/ResultSearch.js
@@ -7,11 +7,34 @@ import { API_ROOT } from '../middleware/api'
// Table
import { BootstrapTable, TableHeaderColumn } from 'react-bootstrap-table';
-class ResultDatabase extends Component {
+const sidebar = 200;
+
+class ResultSearch extends Component {
+ constructor(props) {
+ super(props);
+ this.state = { width: 0, height: 0 };
+ this.updateWindowDimensions = this.updateWindowDimensions.bind(this);
+ }
+ componentWillMount() {
+ this.updateWindowDimensions();
+ window.addEventListener('resize', this.updateWindowDimensions);
+ }
+ componentWillUnmount() {
+ window.removeEventListener('resize', this.updateWindowDimensions);
+ }
+ updateWindowDimensions() {
+ this.setState({ width: window.innerWidth, height: window.innerHeight });
+ }
+ calcWidth = ( dec ) => {
+ let workableWidth = this.state.width - sidebar;
+ return String(workableWidth*dec)
+ }
render() {
- const { results } = this.props
+ const { results } = this.props;
const options = {
- searchPosition: 'left'
+ searchPosition: 'left',
+ defaultSortName: 'analysis',
+ defaultSortOrder: 'asc',
};
if (results.pending){
return Waiting for server response...
@@ -20,16 +43,13 @@ class ResultDatabase extends Component {
} else if (results.fulfilled){
console.log(results)
return (
-
-
# of Genome Files: {results.value.length}
-
- Spfy ID
- Filename
- Submitted
- O-Type
- H-Type
-
-
+
+ Filename
+ Date Submitted
+ Contig ID
+ Analysis
+ Hit
+
);
}
}
@@ -37,4 +57,4 @@ class ResultDatabase extends Component {
export default connect(props => ({
results: {url: API_ROOT + `results/${props.jobId}`}
-}))(ResultDatabase)
+}))(ResultSearch)
diff --git a/src/components/ResultSubtyping.js b/src/components/ResultSubtyping.js
index e3e2802..2156f29 100644
--- a/src/components/ResultSubtyping.js
+++ b/src/components/ResultSubtyping.js
@@ -27,7 +27,7 @@ class ResultSubtyping extends Component {
}
calcWidth = ( dec ) => {
let workableWidth = this.state.width - sidebar;
- return workableWidth*dec
+ return String(workableWidth*dec)
}
render() {
const { results } = this.props;
@@ -47,6 +47,7 @@ class ResultSubtyping extends Component {
Analysis
Hit
Long Hitname
+ ARO Link
Orientation
Start
Stop
diff --git a/src/components/ResultsTemplates.js b/src/components/ResultsTemplates.js
index 4d94e4c..2463258 100644
--- a/src/components/ResultsTemplates.js
+++ b/src/components/ResultsTemplates.js
@@ -8,6 +8,7 @@ import ResultBulk from './ResultBulk'
import ResultMetadata from './ResultMetadata'
import ResultPanseq from './ResultsPanseq'
import { RedirectToken } from '../components/RedirectToken'
+import ResultSearch from './ResultSearch';
const ResultsTemplates = ({ job, ...props }) => {
switch (job.analysis) {
@@ -44,6 +45,10 @@ const ResultsTemplates = ({ job, ...props }) => {
return
+ case "search":
+ return
+
+
default:
return ERROR: no matching analysis view found.
}
diff --git a/src/containers/Fishers.js b/src/containers/Fishers.js
index e62eec9..4d4cbde 100644
--- a/src/containers/Fishers.js
+++ b/src/containers/Fishers.js
@@ -47,7 +47,7 @@ const fdescrip = (step, nextStep, prevStep) => (
-
+
@@ -79,7 +79,8 @@ const fdescrip = (step, nextStep, prevStep) => (
Rationale:
Because analysis modules in biology tend to have different result
formats, graph storage allows comparisons between the results of
- different types without explicit joins. As in the above example, our
+ different types without explicit joins. We treat all nodes in the graph
+ database as available for anlaysis. As in the above example, our
O-type analysis was developed internally whereas the RGI tool was
developed by the CARD initiative doi: 10.1093/nar/gkw1004.
diff --git a/src/containers/Search.js b/src/containers/Search.js
new file mode 100644
index 0000000..fd6f305
--- /dev/null
+++ b/src/containers/Search.js
@@ -0,0 +1,145 @@
+import React, { Component } from 'react';
+// react-md
+import {
+ TextField,
+ Button,
+ Collapse,
+} from 'react-md';
+// redux
+import { connect } from 'react-redux'
+import { addJob } from '../actions'
+// axios
+import axios from 'axios'
+import { API_ROOT } from '../middleware/api'
+// router
+import Loading from '../components/Loading'
+import { RedirectToken } from '../components/RedirectToken'
+
+class Search extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ st: 'gi|1370526529|gb|CP027599.1|',
+ collapsed: false,
+ submitted: false,
+ open: false,
+ jobId: "",
+ hasResult: false,
+ }
+ }
+ toggle = () => {
+ this.setState({ collapsed: !this.state.collapsed });
+ };
+ _updateSt = (value) => {
+ this.setState({ st: value });
+ }
+ _handleSubmit = (e) => {
+ e.preventDefault() // disable default HTML form behavior
+ // Create form.
+ var data = new FormData()
+ data.append('st', this.state.st)
+ // POST
+ axios.post(API_ROOT + 'search', data)
+ .then(response => {
+ console.log("RESPONSE")
+ console.log(response)
+ let jobId = response.data
+ this.setState({ jobId })
+ // Handle the return.
+ this.props.dispatch(addJob(jobId,
+ 'search',
+ new Date().toLocaleString(),
+ String('Search for ' + this.state.st + ' at: ' + new Date().toLocaleString())
+ ))
+ this.setState({ hasResult: true })
+ })
+ };
+ render(){
+ const { st, hasResult, collapsed } = this.state;
+ const { token } = this.props;
+ return (
+
+
+ {/* actual form */}
+ {(!hasResult)?
+
:
+
+ }
+
+ )
+ }
+}
+
+Search = connect()(Search)
+
+export default Search
diff --git a/src/middleware/api.js b/src/middleware/api.js
index cdfd72c..aa5d170 100644
--- a/src/middleware/api.js
+++ b/src/middleware/api.js
@@ -3,6 +3,7 @@ import React from 'react'
const ROOT = window.location.protocol + '//' + window.location.hostname + ':8000/'
// const ROOT = 'https://lfz.corefacility.ca/superphy/spfyapi/'
// const ROOT = 'http://10.139.14.212:8000/'
+// const ROOT = 'http://192.168.5.19:8090/'
// const ROOT = 'http://192.168.5.19:8000/'
// const ROOT = 'https://spfy.enchartus.ca/'
export const API_ROOT = ROOT + 'api/v0/'
@@ -12,7 +13,9 @@ export const version = 'v.6.3.0'
export const analyses = [
{
'analysis':'subtyping',
- 'description':'Serotype, Virulence Factors, Antimicrobial Resistance, Shiga-toxin & Intimin',
+ 'description':(
+ Serotype, Virulence Factors, Antimicrobial Resistance, Shiga-toxin & Intimin
+ ),
'text':(
Upload genome files & determine associated subtypes.
@@ -25,23 +28,39 @@ export const analyses = [
},{
'analysis':'fishers',
'pseudonym':'statistical comparison',
- 'description':"Group database nodes and compare them using Fisher's Exact Test",
+ 'description': (
+
Identify predictive markers for groups of bacteria based on genome content or
+
metadata, using Fisher's Exact Test
+ ),
'text':'Select groups from uploaded genomes & compare for a chosen target datum.'
- }
+ },{
+ 'analysis': 'search',
+ 'pseudonym': 'search by record.id',
+ 'description': (
+ Search database results by record.id
+ ),
+ 'text': ''
+ },
]
export const extra = [
{
'analysis': 'database',
- 'description': 'Status check of database connection',
+ 'description': (
+ Status check of database connection
+ ),
'text': ''
},{
'analysis': 'metadata',
- 'description': 'Submit metadata in the form of a .csv for upload to the database',
+ 'description': (
+ Submit metadata in the form of a .csv for upload to the database
+ ),
'text': ''
},{
'analysis': 'panseq',
- 'description': 'Load a pan-genome into the database for secondary analyses',
+ 'description': (
+ Load a pan-genome into the database for secondary analyses
+ ),
'text': (
Upload genomes & split into pan-genome regions.