gramene-search 1.2.38 → 1.2.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gramene-search",
3
- "version": "1.2.38",
3
+ "version": "1.2.40",
4
4
  "description": "search wrapper for gramene",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -25,7 +25,7 @@
25
25
  "flat-to-nested": "^1.1.1",
26
26
  "formik": "^3.0.0-next.8",
27
27
  "gramene-bins-client": "^2.3.3",
28
- "gramene-dbxrefs": "^3.0.4",
28
+ "gramene-dbxrefs": "^3.0.11",
29
29
  "gramene-genetree-vis": "^4.1.13",
30
30
  "gramene-mdview": "^1.1.8",
31
31
  "gramene-search-vis": "^4.1.10",
@@ -37,16 +37,16 @@
37
37
  "numeral": "^2.0.6",
38
38
  "querystringify": "^2.2.0",
39
39
  "react": "^17.0.2",
40
- "react-bootstrap": "^1.6.3",
41
- "react-debounce-input": "^3.2.3",
40
+ "react-bootstrap": "^2.5.0",
41
+ "react-debounce-input": "^3.2.5",
42
42
  "react-dom": "17.0.2",
43
43
  "react-ga": "^3.3.0",
44
- "react-icons": "^4.1.0",
44
+ "react-icons": "^4.3.1",
45
45
  "react-markdown": "^5.0.3",
46
- "react-router-dom": "^5.2.0",
46
+ "react-router-dom": "^5.3.0",
47
47
  "react-tree-menu": "https://github.com/ajo2995/react-tree-menu",
48
48
  "redux-bundler": "21.0.0",
49
- "redux-bundler-react": "1.0.1",
49
+ "redux-bundler-react": "^1.2.0",
50
50
  "yup": "^0.32.9"
51
51
  },
52
52
  "prettier": {
@@ -57,9 +57,15 @@
57
57
  "@babel/core": "latest",
58
58
  "@babel/preset-env": "latest",
59
59
  "@babel/preset-react": "latest",
60
- "@parcel/transformer-image": "2.0.0",
61
- "@parcel/transformer-less": "2.0.0",
62
- "parcel": "2.0.0"
60
+ "@parcel/config-default": "^2.0.0-rc.0",
61
+ "@parcel/core": "^2.8.0",
62
+ "@parcel/transformer-image": "^2.8.0",
63
+ "@parcel/transformer-js": "^2.8.0",
64
+ "@parcel/transformer-less": "^2.8.0",
65
+ "buffer": "^5.7.1",
66
+ "http-proxy-middleware": "^2.0.6",
67
+ "parcel": "^2.8.0",
68
+ "process": "^0.11.10"
63
69
  },
64
70
  "repository": {
65
71
  "type": "git",
@@ -7,8 +7,9 @@ import Homology from './details/Homology'
7
7
  import Location from './details/Location'
8
8
  import Pathways from "./details/Pathways"
9
9
  import Xrefs from "./details/Xrefs"
10
+ import Publications from "./details/Publications"
10
11
  import {GrFormPrevious, GrFormNextLink, GrFormNext, GrHpe} from 'react-icons/gr'
11
- import { Badge } from 'react-bootstrap'
12
+ import { Badge, OverlayTrigger, Tooltip } from 'react-bootstrap'
12
13
 
13
14
  let external = <small title="This link opens a page from an external site"> <i className="fa fa-external-link"/></small>;
14
15
 
@@ -17,7 +18,8 @@ let inventory = {
17
18
  expression: Expression,
18
19
  homology: Homology,
19
20
  pathways: Pathways,
20
- xrefs: Xrefs
21
+ xrefs: Xrefs,
22
+ pubs: Publications
21
23
  };
22
24
 
23
25
  function renderTairSummary(searchResult) {
@@ -102,31 +104,37 @@ class Gene extends React.Component {
102
104
  {
103
105
  id: 'location',
104
106
  label: 'Location',
107
+ popup: 'Genome Browser',
105
108
  available: false
106
109
  },
107
110
  {
108
111
  id: 'expression',
109
112
  label: 'Expression',
113
+ popup: 'Gene Expression Atlas',
110
114
  available: false
111
115
  },
112
116
  {
113
117
  id: 'homology',
114
118
  label: 'Homology',
119
+ popup: 'Gene Family Tree',
115
120
  available: false
116
121
  },
117
122
  {
118
123
  id: 'pathways',
119
124
  label: 'Pathways',
125
+ popup: 'Plant Reactome Pathways',
126
+ available: false
127
+ },
128
+ {
129
+ id: 'pubs',
130
+ label: 'Papers',
131
+ popup: 'Curated Publications',
120
132
  available: false
121
133
  },
122
- // {
123
- // id: 'pubs',
124
- // label: 'Publications',
125
- // available: false
126
- // },
127
134
  {
128
135
  id: 'xrefs',
129
136
  label: 'Xrefs',
137
+ popup: 'Database Cross-references',
130
138
  available: false
131
139
  }
132
140
  ],
@@ -202,10 +210,18 @@ class Gene extends React.Component {
202
210
  </div>
203
211
  <div className="gene-detail-tabs">
204
212
  {this.state.details.map((d,idx) => (
213
+ <OverlayTrigger
214
+ key={idx}
215
+ placement={'bottom'}
216
+ overlay={
217
+ <Tooltip id={`tooltip`}>{d.popup}</Tooltip>
218
+ }
219
+ >
205
220
  <div key={idx}
206
221
  className={`col-md-1 text-center gene-detail-tab-${this.getDetailStatus(d)}`}
207
222
  onClick={()=>this.setExpanded(d)}
208
223
  >{d.label}</div>
224
+ </OverlayTrigger>
209
225
  ))}
210
226
  </div>
211
227
  {this.state.expandedDetail && this.ensureGene(searchResult.id) && <div className="visible-detail">{React.createElement(inventory[this.state.expandedDetail], this.props)}</div>}
@@ -0,0 +1,145 @@
1
+ import React from 'react'
2
+ import ReactGA from 'react-ga'
3
+ // import {connect} from "redux-bundler-react";
4
+ import _ from 'lodash'
5
+ import dbxrefs from 'gramene-dbxrefs';
6
+ import {Detail, Title, Description, Content} from "./generic";
7
+
8
+ const HOW_MANY_TO_SHOW_BY_DEFAULT = 10;
9
+
10
+ class Xref extends React.Component {
11
+ constructor(props) {
12
+ super(props);
13
+ this.state = {showAll: false};
14
+ }
15
+
16
+ toggleShowAll() {
17
+ this.setState({showAll: !this.state.showAll});
18
+ }
19
+
20
+ possiblyTruncateList(vals) {
21
+ var ellipsis, ellipsisChar, ellipsisTitle;
22
+
23
+ if (vals.length > HOW_MANY_TO_SHOW_BY_DEFAULT) {
24
+ if (this.state.showAll) {
25
+ ellipsisChar = '^ show first ' + HOW_MANY_TO_SHOW_BY_DEFAULT;
26
+ ellipsisTitle = 'Show less';
27
+ }
28
+ else {
29
+ ellipsisChar = '… show all (' + (vals.length - HOW_MANY_TO_SHOW_BY_DEFAULT) + ' more)';
30
+ ellipsisTitle = 'Show more';
31
+ vals = vals.slice(0, HOW_MANY_TO_SHOW_BY_DEFAULT);
32
+ }
33
+
34
+ ellipsis = (
35
+ <li key="showMore" className="showAll">
36
+ <a title={ellipsisTitle} onClick={this.toggleShowAll.bind(this)}>{ellipsisChar}</a>
37
+ </li>
38
+ );
39
+
40
+ vals.push(ellipsis);
41
+ }
42
+
43
+ return vals;
44
+ }
45
+
46
+ render() {
47
+ var db = this.props.xref.label;
48
+ var urlfcn = this.props.xref.url;
49
+
50
+ var members = this.props.members.sort();
51
+
52
+ var vals = members.map(function (item, idx) {
53
+ var url = urlfcn(item),
54
+ liClass = idx < HOW_MANY_TO_SHOW_BY_DEFAULT ? "default" : "extra";
55
+ let external = <small title="This link opens a page from an external site"> <i className="fa fa-external-link"/></small>;
56
+ return (
57
+ <li key={idx} className={liClass}>
58
+ <ReactGA.OutboundLink
59
+ eventLabel={db}
60
+ to={url}
61
+ target="_blank"
62
+ >
63
+ {item}{external}
64
+ </ReactGA.OutboundLink>
65
+ </li>
66
+ )
67
+ })
68
+
69
+ vals = this.possiblyTruncateList(vals);
70
+
71
+ return (
72
+ <tr>
73
+ {/*<td className="xref-name-col">{db}</td>*/}
74
+ <td className="xref-value-col">
75
+ <ol className="xref-id-list">{vals}</ol>
76
+ </td>
77
+ <td className="xref-name-col">{this.props.source}</td>
78
+ <td className="xref-value-col">{this.props.text}</td>
79
+ </tr>
80
+ );
81
+ }
82
+ }
83
+
84
+ function formatPubsForGene(gene) {
85
+ if(!gene || !_.isArray(gene.xrefs)) {
86
+ throw new Error("No xrefs for " + _.get(gene._id));
87
+ }
88
+ return gene.xrefs
89
+ .filter(xr => xr.db === "PUBMED") //dbxrefs.isKnown(xr.db))
90
+ .sort((a,b) => {
91
+ if (a.source) {
92
+ if (b.source) {
93
+ if (a.source < b.source) {
94
+ return -1;
95
+ }
96
+ if (a.source > b.source) {
97
+ return 1;
98
+ }
99
+ }
100
+ else {
101
+ return -1;
102
+ }
103
+ }
104
+ else if (b.source) {
105
+ return 1;
106
+ }
107
+ if (a.db < b.db) {
108
+ return -1;
109
+ }
110
+ if (a.db > b.db) {
111
+ return 1;
112
+ }
113
+ return 0;
114
+ })
115
+ .map((xr,idx) => {
116
+ var xref = dbxrefs.fetch(xr.db);
117
+ return (
118
+ <Xref key={idx} xref={xref} members={xr.ids} source={xr.source} text={xr.text} />
119
+ )
120
+ })
121
+ }
122
+
123
+ const Publications = ({searchResult, geneDocs}) => (
124
+ <Detail>
125
+ <Title key="title">Curated publications</Title>
126
+ <Description key="description">This gene has been described in the literature:</Description>
127
+ <Content key="content">
128
+ <table className="xrefs table">
129
+ <thead>
130
+ <tr>
131
+ <th className="xref-10-col">PubMed link</th>
132
+ <th className="xref-10-col">Curation source</th>
133
+ <th className="xref-80-col">Title/Description</th>
134
+ </tr>
135
+ </thead>
136
+ <tbody>
137
+ {formatPubsForGene(geneDocs[searchResult.id])}
138
+ </tbody>
139
+ </table>
140
+ </Content>
141
+ </Detail>
142
+ );
143
+
144
+ export default Publications;
145
+
@@ -44,20 +44,13 @@ class Xref extends React.Component {
44
44
  }
45
45
 
46
46
  render() {
47
- var members, vals, db;
48
- db = this.props.displayName;
47
+ var db = this.props.xref.label;
48
+ var urlfcn = this.props.xref.url;
49
49
 
50
- members = this.props.members;
50
+ var members = this.props.members.sort();
51
51
 
52
- vals = _(members)
53
- .map(function (m) {
54
- return m.val;
55
- })
56
- .flatten(true)
57
- .sort()
58
- .uniq(true) // TODO figure out why there are duplicates.
59
- .map(function (item, idx) {
60
- var url = members[0].url(item),
52
+ var vals = members.map(function (item, idx) {
53
+ var url = urlfcn(item),
61
54
  liClass = idx < HOW_MANY_TO_SHOW_BY_DEFAULT ? "default" : "extra";
62
55
  let external = <small title="This link opens a page from an external site"> <i className="fa fa-external-link"/></small>;
63
56
  return (
@@ -72,13 +65,12 @@ class Xref extends React.Component {
72
65
  </li>
73
66
  )
74
67
  })
75
- .value();
76
68
 
77
69
  vals = this.possiblyTruncateList(vals);
78
70
 
79
71
  return (
80
72
  <tr>
81
- <td className="xref-name-col">{this.props.displayName}</td>
73
+ <td className="xref-name-col">{db}</td>
82
74
  <td className="xref-value-col">
83
75
  <ol className="xref-id-list">{vals}</ol>
84
76
  </td>
@@ -91,22 +83,15 @@ function formatXrefsForGene(gene) {
91
83
  if(!gene || !_.isArray(gene.xrefs)) {
92
84
  throw new Error("No xrefs for " + _.get(gene._id));
93
85
  }
94
- return _(gene.xrefs)
95
- .keyBy('db')
96
- .pickBy(function(val, name) {
97
- return dbxrefs.isKnown(name);
98
- })
99
- .map(function(val, name) {
100
- var xref = dbxrefs.fetch(name);
101
- return {url: xref.url, label: xref.label, val: val.ids};
102
- })
103
- .groupBy('label')
104
- .map(function(members, displayName) {
86
+ return gene.xrefs
87
+ .filter(xr => dbxrefs.isKnown(xr.db) && xr.db !== "PUBMED")
88
+ .sort()
89
+ .map((xr,idx) => {
90
+ var xref = dbxrefs.fetch(xr.db);
105
91
  return (
106
- <Xref key={displayName} displayName={displayName} members={members} />
92
+ <Xref key={idx} xref={xref} members={xr.ids} source={xr.source} text={xr.text} />
107
93
  )
108
94
  })
109
- .value();
110
95
  }
111
96
 
112
97
  const Xrefs = ({searchResult, geneDocs}) => (
@@ -24,6 +24,15 @@
24
24
  .xref-value-col {
25
25
  width: 80%;
26
26
  }
27
+ .xref-80-col {
28
+ width: 80%;
29
+ }
30
+ .xref-70-col {
31
+ width: 70%;
32
+ }
33
+ .xref-10-col {
34
+ width: 10%;
35
+ }
27
36
  .xref-id-list {
28
37
  padding-left: 0;
29
38
  list-style: none;
package/src/demo.js CHANGED
@@ -44,7 +44,7 @@ const panSites = [
44
44
  ensemblURL: 'https://ensembl.gramene.org',
45
45
  ensemblSite: 'https://ensembl.gramene.org',
46
46
  ensemblRest: 'https://data.gramene.org/ensembl',
47
- grameneData: 'https://data.gramene.org/v64',
47
+ grameneData: 'https://data.gramene.org/v66',
48
48
  targetTaxonId: 3702,
49
49
  alertText: 'Main site'
50
50
  },
package/src/index.html CHANGED
@@ -5,7 +5,7 @@
5
5
  <title>Gramene Search</title>
6
6
  <script>
7
7
  window.gramene = {};
8
- gramene.defaultServer = 'https://data.gramene.org/v65/swagger';
8
+ gramene.defaultServer = 'https://data.gramene.org/v66/swagger';
9
9
  </script>
10
10
  <script async src="./static/gramene-dalliance/dalliance-all.js"></script>
11
11
  <script async src="https://plantreactome.gramene.org/DiagramJs/diagram/diagram.nocache.js"></script>
@@ -1,2 +0,0 @@
1
- 43337522
2
- 1663863196280298000