Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 153 additions & 2 deletions rnacentral/portal/static/css/gene.css
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,6 @@
border-radius: 12px;
padding: 1.5rem;
margin-bottom: 1.5rem;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
border-left: 4px solid #3498db;
}

.gene__widget-header {
Expand Down Expand Up @@ -595,4 +593,157 @@ text-decoration: none;
font-size: 0.9rem;
padding: 0.5rem 0.75rem;
}
}

/* LitSumm Carousel Section */
.gene__litsumm-section {
background: #f8f9fa;
padding: 1.5rem 0;
border-bottom: 1px solid #e9ecef;
overflow: visible;
}

.gene__litsumm-header {
text-align: center;
margin-bottom: 1rem;
}

.gene__litsumm-title {
font-size: 1.5rem;
font-weight: 600;
color: #2c3e50;
margin-bottom: 0.25rem;
margin-top: 0;
}
.gene__litsumm-subtitle {
padding-inline: 10px;
padding-block-end: 20px;
margin: 0;
}
.gene__litsumm-subtitle span {
color: rgb(38, 183, 231);
font-size: 1.4rem;
font-weight: bold;
}

.gene__litsumm-caution {
color: #8a6d3b;
background-color: #fcf8e3;
border-color: #faebcc;
padding: 15px;
border-radius: 4px;
margin-block-end: 20px;
}

.gene__litsumm-caution a {
color: #3498db;
text-decoration: none;
}

.gene__litsumm-caution a:hover {
text-decoration: underline;
}

.gene__litsumm-carousel {
margin: 0 auto;
padding: 0 40px;
position: relative;
}

.gene__litsumm-panel {
padding: 20px;
margin: 0 0.5rem;
cursor: pointer;
transition: transform 0.2s ease, box-shadow 0.2s ease;
border-radius: 8px;
}

.gene__litsumm-panel:hover {
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
}

.gene__litsumm-id {
margin: 0 0 10px 0;
font-size: 18px;
font-weight: 500;
}

.gene__litsumm-summary {
font-size: 14px;
line-height: 1.6;
color: #333;
margin: 0;
}

.gene__litsumm-summary a {
color: #3498db;
text-decoration: none;
}

.gene__litsumm-summary a:hover {
text-decoration: underline;
}

/* Slick carousel overrides for litsumm */
.gene__litsumm-carousel .slick-list {
overflow: hidden;
}

.gene__litsumm-carousel .slick-track {
display: flex;
align-items: stretch;
}

.gene__litsumm-carousel .slick-slide {
visibility: hidden;
opacity: 0;
transition: opacity 0.3s ease;
}

.gene__litsumm-carousel .slick-slide.slick-active {
visibility: visible;
opacity: 1;
}

.gene__litsumm-carousel .slick-prev {
left: 0;
}

.gene__litsumm-carousel .slick-next {
right: 0;
}

.gene__litsumm-carousel .slick-prev:before,
.gene__litsumm-carousel .slick-next:before {
color: #9e9e9e;
}

.gene__litsumm-carousel .slick-disabled {
cursor:not-allowed;
}

.gene__litsumm-carousel .slick-disabled:before {
opacity: 0.25;
}

.gene__litsumm-carousel .slick-dots {
bottom: -30px;
}

.gene__litsumm-carousel .slick-dots li button:before {
color: #3498db;
}

@media (max-width: 768px) {
.gene__litsumm-section {
padding: 1rem 0;
}

.gene__litsumm-title {
font-size: 1.25rem;
}

.gene__litsumm-panel {
padding: 1rem;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ var geneDetail = {
geneFound: '@?'
},
controllerAs: 'vm',
controller: ['$timeout', '$element', '$scope', '$http', function($timeout, $element, $scope, $http) {
controller: ['$timeout', '$element', '$scope', '$http', '$sce', function($timeout, $element, $scope, $http, $sce) {
var vm = this;

// State management
Expand Down Expand Up @@ -49,6 +49,7 @@ var geneDetail = {

vm.transcripts = [];
vm.externalLinks = [];
vm.litsummSummaries = [];

vm.$onInit = function() {

Expand All @@ -70,10 +71,20 @@ var geneDetail = {
if (globalData.geneData) {
processGeneData(globalData.geneData);

// Set transcripts and external links from global data
// Set transcripts, external links, and litsumm summaries from global data
vm.transcripts = globalData.transcriptsData || [];
vm.externalLinks = globalData.externalLinksData || [];

// Process litsumm summaries and trust HTML content
var rawSummaries = globalData.litsummSummaries || [];
vm.litsummSummaries = rawSummaries.map(function(item) {
return {
id: item.id,
urs: item.urs,
summary: $sce.trustAsHtml(item.summary)
};
});

// parse urs and taxid for each transcript

if(vm.transcripts && vm.transcripts.length > 0) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
(function() {
'use strict';

angular.module('geneDetail', []);
angular.module('geneDetail', ['ngSanitize']);
})();
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,27 @@ <h2 class="gene__widget-title">Gene Summary</h2>
</div>
</header>

<section class="gene__litsumm-section" ng-if="vm.litsummSummaries && vm.litsummSummaries.length > 0">
<div class="gene-container">
<div class="gene__litsumm-header">
<p class="gene__litsumm-caution">
Caution, this is an AI generated summary based on literature. This may have errors, see <a href="/help/litsumm" target="_blank">here for more</a>.
Please share your <a href="" onclick="$('.doorbell-feedback').click(); changePlaceholder();">feedback</a> with us.
</p>
</div>
<div id="gene-litsumm-carousel" class="gene__litsumm-carousel">
<div class="panel panel-default gene__litsumm-panel"
ng-repeat="item in vm.litsummSummaries">
<div class="gene__litsumm-subtitle">
<span ng-bind-html="item.urs"></span> - <span>{{vm.geneData.summary}}</span>
</div>

<p class="gene__litsumm-summary" ng-bind-html="item.summary"></p>
</div>
</div>
</div>
</section>

<main class="gene__main-content">
<div class="gene-container">
<div class="gene__tabs">
Expand Down
36 changes: 36 additions & 0 deletions rnacentral/portal/templates/portal/gene_detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,43 @@ <h4 class="alert-heading">Gene Not Found</h4>
transcriptsData: {{ transcriptsData|safe }},
externalLinksData: {{ externalLinksData|safe }},
transcriptsPagination: {{ transcriptsPagination|safe }},
litsummSummaries: {{ litsummSummaries|safe }},
geneFound: {{ geneFound|yesno:'true,false' }}
};
</script>
{% endblock %}

{% block extra_js_uncompressed %}
<script>
$(document).ready(function() {
var litsummData = window.geneDetailData.litsummSummaries || [];
if (litsummData.length > 1) {
// Poll until the carousel element exists and has items
var attempts = 0;
var maxAttempts = 50;

var initCarousel = function() {
attempts++;
var $carousel = $('#gene-litsumm-carousel');

if ($carousel.length && $carousel.find('.gene__litsumm-panel').length > 0) {
if (!$carousel.hasClass('slick-initialized')) {
$carousel.slick({
draggable: true,
dots: true,
infinite: false,
slidesToShow: 1,
slidesToScroll: 1,
arrows: true
});
}
} else if (attempts < maxAttempts) {
setTimeout(initCarousel, 100);
}
};

setTimeout(initCarousel, 500);
}
});
</script>
{% endblock %}
38 changes: 37 additions & 1 deletion rnacentral/portal/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,7 @@ def gene_detail(request, name):
"transcriptsData": [],
"externalLinksData": [],
"transcriptsPagination": {},
"litsummSummaries": [],
})

metadata = getattr(gene, "metadata", None)
Expand Down Expand Up @@ -586,9 +587,43 @@ def gene_detail(request, name):
}


# External links data
# External links data
external_links_data = []

# Fetch litsumm summaries for all transcripts of this gene
litsumm_summaries_data = []

# Get all litsumm summaries for transcripts of this gene
with connection.cursor() as cursor:
cursor.execute("""
SELECT ls.primary_id, ls.display_id, ls.summary
FROM rnc_gene_members gm
JOIN rnc_genes g ON gm.rnc_gene_id = g.id
JOIN rnc_sequence_regions locus ON locus.id = gm.locus_id
JOIN litsumm_summaries ls ON ls.primary_id = locus.urs_taxid
WHERE g.public_name = %s
""", [gene.name])
rows = cursor.fetchall()

pmc_regex = re.compile(r"PMC[0-9]+")
seen_ids = set()
for row in rows:
primary_id, display_id, summary = row
# Skip duplicates
if primary_id in seen_ids:
continue
seen_ids.add(primary_id)
# Convert PMC IDs to links
summary_with_links = pmc_regex.sub(
r'<a href="https://europepmc.org/article/PMC/\g<0>" target="_blank">\g<0></a>',
summary,
)
litsumm_summaries_data.append({
"id": display_id,
"urs": primary_id,
"summary": summary_with_links,
})

return render(request, "portal/gene_detail.html", {
"geneName": base_name,
"geneVersion": version,
Expand All @@ -597,6 +632,7 @@ def gene_detail(request, name):
'transcriptsData': json.dumps(transcripts_data),
'externalLinksData': json.dumps(external_links_data),
'transcriptsPagination': json.dumps(pagination),
'litsummSummaries': json.dumps(litsumm_summaries_data),
})


Expand Down