Skip to content

Commit 1126a61

Browse files
committed
Merge branch 'release-1.1.2'
2 parents dd3734c + be399cb commit 1126a61

20 files changed

+445
-91
lines changed

pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
<groupId>ubc.pavlab</groupId>
77
<artifactId>rdp</artifactId>
8-
<version>1.1.1</version>
8+
<version>1.1.2</version>
99

1010
<parent>
1111
<groupId>org.springframework.boot</groupId>

src/main/java/ubc/pavlab/rdp/controllers/LoginController.java

+9
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import org.apache.commons.logging.LogFactory;
55
import org.springframework.beans.factory.annotation.Autowired;
66
import org.springframework.context.ApplicationEventPublisher;
7+
import org.springframework.security.authentication.AnonymousAuthenticationToken;
78
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
89
import org.springframework.security.core.Authentication;
910
import org.springframework.security.core.context.SecurityContextHolder;
@@ -39,6 +40,14 @@ public class LoginController {
3940
@RequestMapping(value = {"/login"}, method = RequestMethod.GET)
4041
public ModelAndView login() {
4142
ModelAndView modelAndView = new ModelAndView();
43+
44+
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
45+
46+
if (!(auth instanceof AnonymousAuthenticationToken)) {
47+
// User is logged in
48+
return new ModelAndView("forward:/");
49+
}
50+
4251
modelAndView.setViewName( "login" );
4352
return modelAndView;
4453
}

src/main/java/ubc/pavlab/rdp/controllers/MainController.java

-25
Original file line numberDiff line numberDiff line change
@@ -101,31 +101,6 @@ public ModelAndView getTermsGenesForTaxon( @PathVariable Integer taxonId, @PathV
101101
return modelAndView;
102102
}
103103

104-
@RequestMapping(value = "/user/{userId}/profile", method = RequestMethod.GET)
105-
public ModelAndView viewUserProfile( @PathVariable Integer userId ) {
106-
ModelAndView modelAndView = new ModelAndView();
107-
User user = userService.findUserById( userId );
108-
109-
modelAndView.addObject( "user", user );
110-
modelAndView.addObject( "viewOnly", true);
111-
modelAndView.setViewName( "user/profile" );
112-
return modelAndView;
113-
}
114-
115-
@RequestMapping(value = "/user/{userId}/model/{taxonId}", method = RequestMethod.GET)
116-
public ModelAndView viewUserModel( @PathVariable Integer userId, @PathVariable Integer taxonId ) {
117-
ModelAndView modelAndView = new ModelAndView();
118-
User user = userService.findUserById( userId );
119-
120-
Taxon taxon = taxonService.findById( taxonId );
121-
122-
modelAndView.addObject( "user", user );
123-
modelAndView.addObject( "taxon", taxon );
124-
modelAndView.addObject( "viewOnly", true);
125-
modelAndView.setViewName( "user/model" );
126-
return modelAndView;
127-
}
128-
129104
@RequestMapping(value = {"/user/profile"}, method = RequestMethod.GET)
130105
public ModelAndView profile() {
131106
ModelAndView modelAndView = new ModelAndView();

src/main/java/ubc/pavlab/rdp/controllers/ManagerController.java

+18
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import org.apache.commons.logging.LogFactory;
55
import org.springframework.beans.factory.annotation.Autowired;
66
import org.springframework.stereotype.Controller;
7+
import org.springframework.web.bind.annotation.PathVariable;
78
import org.springframework.web.bind.annotation.RequestMapping;
89
import org.springframework.web.bind.annotation.RequestMethod;
910
import org.springframework.web.bind.annotation.RequestParam;
@@ -137,6 +138,23 @@ public ModelAndView searchUsersByGeneView( @RequestParam String symbol, @Request
137138
return modelAndView;
138139
}
139140

141+
@RequestMapping(value = "/manager/view/{userId}", method = RequestMethod.GET)
142+
public ModelAndView viewUser( @PathVariable Integer userId ) {
143+
ModelAndView modelAndView = new ModelAndView();
144+
User user = userService.findCurrentUser();
145+
User viewUser = userService.findUserById( userId );
146+
147+
if ( viewUser == null) {
148+
modelAndView.setViewName( "error/404" );
149+
} else {
150+
modelAndView.addObject( "user", user );
151+
modelAndView.addObject( "viewUser", viewUser );
152+
modelAndView.addObject( "viewOnly", true );
153+
modelAndView.setViewName( "manager/view" );
154+
}
155+
return modelAndView;
156+
}
157+
140158
private Collection<UserGene> handleGeneSymbolSearch( String symbolLike, TierType tier, Taxon taxon) {
141159
if ( tier.equals( TierType.ANY ) ) {
142160
return userGeneService.findByLikeSymbol( symbolLike, taxon );

src/main/java/ubc/pavlab/rdp/controllers/UserController.java

-3
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,6 @@ public Collection<UserTerm> getRecommendedTermsForTaxon( @PathVariable Integer t
126126
Taxon taxon = taxonService.findById( taxonId );
127127
Collection<UserTerm> terms = userService.recommendTerms( user, taxon );
128128

129-
// Remove terms already added
130-
terms.removeAll( user.getTermsByTaxon( taxon ) );
131-
132129
return terms;
133130
}
134131

src/main/java/ubc/pavlab/rdp/model/User.java

+6
Original file line numberDiff line numberDiff line change
@@ -107,4 +107,10 @@ public Set<UserTerm> getTermsByTaxon( Taxon taxon ) {
107107
public boolean hasTaxon( Taxon taxon ) {
108108
return this.getUserGenes().values().stream().anyMatch( g -> g.getTaxon().equals( taxon ) );
109109
}
110+
111+
@JsonIgnore
112+
@Transient
113+
public Set<Taxon> getTaxons() {
114+
return this.getUserGenes().values().stream().map( Gene::getTaxon ).collect( Collectors.toSet() );
115+
}
110116
}

src/main/java/ubc/pavlab/rdp/services/UserServiceImpl.java

+8-3
Original file line numberDiff line numberDiff line change
@@ -254,15 +254,20 @@ public Collection<UserTerm> recommendTerms( User user, Taxon taxon, int minSize,
254254
if ( maxSize > 0 ) {
255255
resultStream = resultStream.filter( e -> e.getKey().getSize( taxon ) <= maxSize );
256256
}
257-
// Then keep only those terms with the highest frequency
257+
258+
Set<UserTerm> userTerms = user.getTermsByTaxon( taxon );
259+
260+
// Then keep only those terms not already added and with the highest frequency
258261
Set<UserTerm> topResults = resultStream.map( e -> {
259262
UserTerm ut = new UserTerm( e.getKey(), taxon, null );
260263
ut.setFrequency( e.getValue().intValue() );
261264
return ut;
262-
} ).collect( maxSet( comparing( UserTerm::getFrequency ) ) );
265+
} ).filter( ut -> !userTerms.contains( ut ))
266+
.collect( maxSet( comparing( UserTerm::getFrequency ) ) );
263267

264268
// Keep only leafiest of remaining terms (keep if it has no descendants in results)
265-
return topResults.stream().filter( ut -> Collections.disjoint( topResults, goService.getDescendants( ut ) ) ).collect( Collectors.toSet() );
269+
return topResults.stream().filter( ut -> Collections.disjoint( topResults, goService.getDescendants( ut ) ) )
270+
.collect( Collectors.toSet() );
266271
}
267272

268273
private boolean updateOrInsert( User user, Gene gene, TierType tier ) {

src/main/java/ubc/pavlab/rdp/util/Gene2GoParser.java

+12-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import org.apache.commons.logging.LogFactory;
55
import org.apache.commons.net.ftp.FTP;
66
import org.apache.commons.net.ftp.FTPClient;
7+
import org.apache.commons.net.ftp.FTPHTTPClient;
78
import ubc.pavlab.rdp.model.Gene;
89
import ubc.pavlab.rdp.model.GeneOntologyTerm;
910
import ubc.pavlab.rdp.model.Taxon;
@@ -32,7 +33,17 @@ public class Gene2GoParser {
3233

3334
public static void populateAnnotations( URL url, Collection<Taxon> acceptableTaxons, GeneService geneService, GOService goService ) throws ParseException {
3435

35-
FTPClient ftp = new FTPClient();
36+
String proxyHost = System.getProperty( "ftp.proxyHost" );
37+
38+
FTPClient ftp;
39+
40+
if ( proxyHost != null ) {
41+
Integer proxyPort = Integer.parseInt( System.getProperty( "ftp.proxyPort" ) );
42+
log.info( "Using HTTP proxy server: " + proxyHost + ":" + proxyPort.toString() );
43+
ftp = new FTPHTTPClient( proxyHost, proxyPort );
44+
} else {
45+
ftp = new FTPClient();
46+
}
3647

3748
try {
3849

src/main/java/ubc/pavlab/rdp/util/GeneInfoParser.java

+12-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import org.apache.commons.logging.LogFactory;
55
import org.apache.commons.net.ftp.FTP;
66
import org.apache.commons.net.ftp.FTPClient;
7+
import org.apache.commons.net.ftp.FTPHTTPClient;
78
import ubc.pavlab.rdp.model.Gene;
89
import ubc.pavlab.rdp.model.Taxon;
910

@@ -28,7 +29,17 @@ public class GeneInfoParser {
2829

2930
public static Set<Gene> parse( Taxon taxon, URL url ) throws ParseException {
3031

31-
FTPClient ftp = new FTPClient();
32+
String proxyHost = System.getProperty( "ftp.proxyHost" );
33+
34+
FTPClient ftp;
35+
36+
if ( proxyHost != null ) {
37+
Integer proxyPort = Integer.parseInt( System.getProperty( "ftp.proxyPort" ) );
38+
log.info( "Using HTTP proxy server: " + proxyHost + ":" + proxyPort.toString() );
39+
ftp = new FTPHTTPClient( proxyHost, proxyPort );
40+
} else {
41+
ftp = new FTPClient();
42+
}
3243

3344
try {
3445

src/main/resources/static/css/common.css

+21
Original file line numberDiff line numberDiff line change
@@ -164,4 +164,25 @@ tr.new-row {
164164
/* Fix duplicate scroll icons on datatable with scrollY enabled*/
165165
.dataTables_scrollBody thead {
166166
visibility: hidden;
167+
}
168+
169+
/* Fixed header scrollable table */
170+
171+
table.table-fixed tr {
172+
width: 100%;
173+
display: inline-table;
174+
/*height:60px;*/
175+
table-layout: fixed;
176+
177+
}
178+
179+
table.table-fixed {
180+
height:220px;
181+
display: -moz-groupbox;
182+
}
183+
table.table-fixed tbody{
184+
overflow-y: scroll;
185+
height: 200px;
186+
/*width: 100%;*/
187+
position: absolute;
167188
}

src/main/resources/static/css/profile.css

+2
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,6 @@
1010

1111
input.data-edit {
1212
width: 90%;
13+
-ms-text-overflow: ellipsis;
14+
text-overflow: ellipsis;
1315
}

src/main/resources/static/js/view.js

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
$(document).ready(function () {
2+
3+
$('#publication-table').DataTable({
4+
"scrollY": "200px",
5+
"scrollCollapse": true,
6+
"paging": false,
7+
"searching": false,
8+
"info": false,
9+
"order": [[ 0, "desc" ]]
10+
});
11+
12+
$('.gene-table').DataTable({
13+
"scrollY": "200px",
14+
"scrollCollapse": true,
15+
"paging": false,
16+
"searching": false,
17+
"info": false,
18+
"order": [[2, "asc"], [0, "desc"]],
19+
"columnDefs": [
20+
{"name": "Symbol", "targets": 0},
21+
{"name": "Name", "targets": 1},
22+
{"name": "Primary", "targets": 2, "className": "text-center", "orderDataType": "dom-checkbox"}
23+
],
24+
"footerCallback": function (row, data, start, end, display) {
25+
var api = this.api();
26+
var columnData = api.columns().data();
27+
var tiers = columnData[columnData.length - 1];
28+
var counts = tiers.reduce(function (acc, curr) {
29+
acc[curr] ? acc[curr]++ : acc[curr] = 1;
30+
return acc;
31+
}, {});
32+
$(api.column(1).footer()).html(
33+
"<b>" + (counts['TIER1'] ? counts['TIER1'] : "0") + "</b> TIER1 <span style='margin: 1em;border-left: 3px solid #F2F7F9;'/> " +
34+
"<b>" + (counts['TIER2'] ? counts['TIER2'] : "0") + "</b> TIER2 <span style='margin: 1em;border-left: 3px solid #F2F7F9;'/> " +
35+
"<b>" + (counts['TIER3'] ? counts['TIER3'] : "0") + "</b> TIER3"
36+
);
37+
38+
}
39+
});
40+
41+
$('.term-table').DataTable({
42+
"scrollY": "200px",
43+
"scrollCollapse": true,
44+
"paging": false,
45+
"searching": false,
46+
"info": false,
47+
"order": [[0, "desc"]]
48+
});
49+
50+
$('#overlapModal').on('show.bs.modal', function (e) {
51+
52+
var taxon_id = $(e.relatedTarget).closest('div.tab-pane')[0].id.split("-")[1];
53+
console.log(taxon_id);
54+
var goId = $(e.relatedTarget).closest('tr').find('td')[0].innerText;
55+
$("#overlapModal").find(".modal-body").load("/user/taxon/" + taxon_id + "/term/" + goId + "/gene/view");
56+
});
57+
58+
$('.terms-tab').on('shown.bs.tab', function (e) {
59+
$('.term-table').DataTable().draw();
60+
})
61+
});

src/main/resources/templates/fragments/gene-table.html

+12-6
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
<thead class="thead-light">
77
<tr>
88
<th scope="col">Symbol</th>
9-
<th scope="col" style="display: none;">Id</th>
9+
<th scope="col" style="display: none;" th:if="${viewOnly == null}">Id</th>
1010
<th scope="col">Name</th>
11-
<th class="text-center" scope="col">Primary</th>
11+
<th class="text-center" scope="col" th:text="${viewOnly == null} ? 'Primary' : 'Tier'">Primary</th>
1212
</tr>
1313
</thead>
1414
<tbody>
@@ -17,14 +17,20 @@
1717
<td><span class="align-middle"><i th:if="${viewOnly == null}" class="delete-row align-middle"/><a
1818
th:href="'https://www.ncbi.nlm.nih.gov/gene/' + ${gene.geneId}"
1919
target="_blank" class="align-middle" th:text="${gene.symbol}"></a></span></td>
20-
<td style="display: none;"><span th:text="${gene.geneId}" th:remove="tag"></span></td>
20+
<td style="display: none;" th:if="${viewOnly == null}"><span th:text="${gene.geneId}" th:remove="tag"></span></td>
2121
<td><span class="align-middle" th:text="${gene.name}"></span></td>
22-
<td class="text-center"><input type="checkbox" class="align-middle" th:disabled="${viewOnly != null}"
23-
th:checked="${gene.tier == T(ubc.pavlab.rdp.model.enums.TierType).TIER1}"/>
24-
</td>
22+
<td class="text-center" th:if="${viewOnly != null}"><span th:text="${gene.tier}" th:remove="tag"></span></td>
23+
<td class="text-center" th:if="${viewOnly == null}"><input type="checkbox" class="align-middle" th:checked="${gene.tier == T(ubc.pavlab.rdp.model.enums.TierType).TIER1}"/></td>
2524
</tr>
2625
</th:block>
2726
</tbody>
27+
<tfoot th:if="${viewOnly != null}">
28+
<tr>
29+
<td colspan="3">
30+
31+
</td>
32+
</tr>
33+
</tfoot>
2834
</table>
2935
</body>
3036
</html>

src/main/resources/templates/fragments/header.html

+3-7
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,13 @@ <h1 class="text-uppercase font-weight-bold m-0">Rare Diseases</h1>
2121
<a class="nav-link" th:href="@{/user/home}" href="/">Home</a>
2222
</li>
2323
<li class="nav-item">
24-
<a th:if="${viewOnly != null}" class="nav-link" th:href="@{'/user/' + ${user.id} + '/profile'}">View Profile</a>
25-
<a th:if="${viewOnly == null}" class="nav-link" th:href="@{/user/profile}" href="/user/profile">Profile</a>
24+
<a class="nav-link" th:href="@{/user/profile}" href="/user/profile">Profile</a>
2625
</li>
2726
<li class="nav-item dropdown">
28-
<a class="nav-link dropdown-toggle" href="/user/model" id="navbarDropdownModel" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
29-
<span th:text="${viewOnly == null} ? 'Model Organisms' : 'View Model Organisms'" th:remove="tag"></span>
30-
</a>
27+
<a class="nav-link dropdown-toggle" href="/user/model" id="navbarDropdownModel" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Model Organisms</a>
3128
<div class="dropdown-menu" aria-labelledby="navbarDropdownModel">
3229
<th:block th:each="taxon : ${@taxonService.findByActiveTrue()}">
33-
<a th:if="${viewOnly != null}" class="dropdown-item text-capitalize" th:classappend="${user.hasTaxon(taxon)} ? 'hastaxon' : ''" th:href="@{'/user/' + ${user.id} + '/model/' + ${taxon.id}}" th:text="${taxon.commonName} " href="#"></a>
34-
<a th:if="${viewOnly == null}" class="dropdown-item text-capitalize" th:classappend="${user.hasTaxon(taxon)} ? 'hastaxon' : ''" th:href="@{'/user/model/' + ${taxon.id}}" th:text="${taxon.commonName} " href="#"></a>
30+
<a class="dropdown-item text-capitalize" th:classappend="${user.hasTaxon(taxon)} ? 'hastaxon' : ''" th:href="@{'/user/model/' + ${taxon.id}}" th:text="${taxon.commonName} " href="#"></a>
3531
</th:block>
3632
</div>
3733
</li>

src/main/resources/templates/fragments/user-table.html

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
</tr>
2020
<th:block th:each="u : ${users}" th:if="${not #lists.isEmpty(users)}">
2121
<tr>
22-
<td><a th:href="@{'/user/' + ${u.id} + '/profile'}" th:text="${u.email}" target="_blank"></a></td>
22+
<td><a th:href="@{'/manager/view/' + ${u.id}}" th:text="${u.email}" target="_blank"></a></td>
2323
<td><span th:text="${u.profile.name}" th:remove="tag"></span></td>
2424
<td><span th:text="${u.profile.lastName}" th:remove="tag"></span></td>
2525
<td><span th:text="${u.profile.organization}" th:remove="tag"></span></td>
@@ -48,7 +48,7 @@
4848
</tr>
4949
<th:block th:each="ug : ${usergenes}" th:if="${not #lists.isEmpty(usergenes)}">
5050
<tr>
51-
<td><a th:href="@{'/user/' + ${ug.user.id} + '/profile'}" th:text="${ug.user.email}" target="_blank"></a></td>
51+
<td><a th:href="@{'/manager/view/' + ${ug.user.id}}" th:text="${ug.user.email}" target="_blank"></a></td>
5252
<td><span th:text="${ug.user.profile.name}" th:remove="tag"></span></td>
5353
<td><span th:text="${ug.user.profile.lastName}" th:remove="tag"></span></td>
5454
<td><span th:text="${ug.user.profile.organization}" th:remove="tag"></span></td>

0 commit comments

Comments
 (0)