diff --git a/rnacentral/portal/static/css/gene.css b/rnacentral/portal/static/css/gene.css index 748f2350d..c4c9ebe43 100644 --- a/rnacentral/portal/static/css/gene.css +++ b/rnacentral/portal/static/css/gene.css @@ -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 { @@ -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; + } } \ No newline at end of file diff --git a/rnacentral/portal/static/js/components/gene-detail/gene-detail.component.js b/rnacentral/portal/static/js/components/gene-detail/gene-detail.component.js index 1dde6bcd4..ae8959ffc 100644 --- a/rnacentral/portal/static/js/components/gene-detail/gene-detail.component.js +++ b/rnacentral/portal/static/js/components/gene-detail/gene-detail.component.js @@ -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 @@ -49,6 +49,7 @@ var geneDetail = { vm.transcripts = []; vm.externalLinks = []; + vm.litsummSummaries = []; vm.$onInit = function() { @@ -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) { diff --git a/rnacentral/portal/static/js/components/gene-detail/gene-detail.module.js b/rnacentral/portal/static/js/components/gene-detail/gene-detail.module.js index 316f90d96..85ac3339f 100644 --- a/rnacentral/portal/static/js/components/gene-detail/gene-detail.module.js +++ b/rnacentral/portal/static/js/components/gene-detail/gene-detail.module.js @@ -1,5 +1,5 @@ (function() { 'use strict'; - angular.module('geneDetail', []); + angular.module('geneDetail', ['ngSanitize']); })(); \ No newline at end of file diff --git a/rnacentral/portal/static/js/components/gene-detail/gene-detail.template.html b/rnacentral/portal/static/js/components/gene-detail/gene-detail.template.html index 12b064e63..f0b167e0d 100644 --- a/rnacentral/portal/static/js/components/gene-detail/gene-detail.template.html +++ b/rnacentral/portal/static/js/components/gene-detail/gene-detail.template.html @@ -45,6 +45,27 @@

Gene Summary

+
+
+
+

+ Caution, this is an AI generated summary based on literature. This may have errors, see here for more. + Please share your feedback with us. +

+
+ +
+
+
diff --git a/rnacentral/portal/templates/portal/gene_detail.html b/rnacentral/portal/templates/portal/gene_detail.html index 889383fee..5f27d83c8 100644 --- a/rnacentral/portal/templates/portal/gene_detail.html +++ b/rnacentral/portal/templates/portal/gene_detail.html @@ -34,7 +34,43 @@

Gene Not Found

transcriptsData: {{ transcriptsData|safe }}, externalLinksData: {{ externalLinksData|safe }}, transcriptsPagination: {{ transcriptsPagination|safe }}, + litsummSummaries: {{ litsummSummaries|safe }}, geneFound: {{ geneFound|yesno:'true,false' }} }; +{% endblock %} + +{% block extra_js_uncompressed %} + {% endblock %} \ No newline at end of file diff --git a/rnacentral/portal/views.py b/rnacentral/portal/views.py index 73eec3626..572fafbd6 100644 --- a/rnacentral/portal/views.py +++ b/rnacentral/portal/views.py @@ -504,6 +504,7 @@ def gene_detail(request, name): "transcriptsData": [], "externalLinksData": [], "transcriptsPagination": {}, + "litsummSummaries": [], }) metadata = getattr(gene, "metadata", None) @@ -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'\g<0>', + 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, @@ -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), })