<template> <div> <div class="inline-block bg-red-500 no-underline font-bold mb-4" /> <a ref="download" /> <table :id="id" class="table table-striped table-bordered table-hover" width="100%" /> <the-action-modal v-if="toggleActionModal" :protein-uniprot="uniprotId" :show="toggleActionModal" :pubmed="pubmed" :canonical-id="canonicaliD" :protein-evidence-score="proteinConfidenceScore" :protein-functional-type="proteinFunctionalTypeData" :protein-experimental-evidence="proteinExperimentalEvidenceData" :protein-driver-criterion="proteinDriverCriterionData" @close="closeModal" /> <the-delete-modal v-if="toggleDeleteModal" :show="toggleDeleteModal" :canonical-id="canonicalId" :uniprot-id="uniprotId" @cancel="closeDeleteModal" /> </div> </template> <script> import TheActionModal from './UI/TheActionModal.vue'; import TheDeleteModal from './UI/TheDeleteModal.vue'; import {apikey} from '@/components/js/const'; const _ = require('lodash'); const $ = (window.jQuery = require('jquery')); require('./js/clipboard'); require('@/components/js/datatable'); let table; const scoreMap = { 'http://llps.biocuckoo.cn/': 1, 'http://db.phasep.pro/browse/highthroughput/': 2, 'http://db.phasep.pro/browse/reviewed/': 4, 'http://db.phasep.pro/browse/uniprotreviewed/': 4, 'http://bio-comp.org.cn/llpsdb/': 4, 'https://phasepro.elte.hu/': 4, 'https://pubmed.ncbi.nlm.nih.gov/': 4, 'https://ddcode.org/': 5, }; function getStartWith(url) { let ret = ''; _.forEach(_.keys(scoreMap), (i) => { if (url.startsWith(i)) { ret = i; } }); return ret; } function getRating(data) { const rating = data; const r = ['<div style="white-space: nowrap;">']; for (let i = 0; i < 5; i++) { if (i < rating) { if (rating - i === 0.5) { r.push('<span class="fa fa-star-half-o checked"/>'); } else { r.push('<span class="fa fa-star checked"/>'); } } else { r.push('<span class="fa fa-star"/>'); } } r.push('</div>'); return r; } export default { name: 'LlpsTable', components: { TheActionModal, TheDeleteModal, }, props: [ 'id', 'data', 'map', 'pubmed', 'dbTags', 'isExperimental', 'canonicalId', 'proteinDriverCriterion', 'proteinExperimentalEvidence', 'proteinFunctionalType', ], data() { return { toggleActionModal: false, toggleDeleteModal: false, uniprotId: '', selectedRowData: '', canonicaliD: '', proteinConfidenceScore: 0, proteinFunctionalTypeData: '', proteinExperimentalEvidenceData: '', proteinDriverCriterionData: '', }; }, mounted() { const vm = this; vm.createTable(vm.id, vm.data); }, methods: { closeModal() { this.toggleActionModal = false; this.$emit('update-key'); }, closeDeleteModal() { this.toggleDeleteModal = false; this.$emit('update-key'); }, fetchProtein(uniprot_id) { const vm = this; // eslint-disable-next-line const url = `/protein/${uniprot_id}`; // // eslint-disable-next-line // console.log(url) // this.$router.push(url) // window.open(url); vm.$router.push(url) }, forwardUniprot(uniprot_id) { const vm = this; // eslint-disable-next-line const url = `https://www.uniprot.org/uniprot/${uniprot_id}`; // // eslint-disable-next-line // console.log(url) // window.open(url); vm.$router.push(url) }, createLink(link) { return `<a href="${link}" class="external-link tooltipped tooltipped-n tooltipped-multiline" aria-label="Clicking this link opens Evidence page." target="_blank"> ${link} </a>`; }, createPubMedLink(item) { return `<a id="${item}" href="https://pubmed.ncbi.nlm.nih.gov/${item}" class="pubmed-link tooltipped tooltipped-n tooltipped-multiline" target="_blank"> ${item} <i class="glyphicon glyphicon-link"></i> </a>`; }, fetchPubMedId(item) { // console.log(item) if (item) { const url = 'https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esummary.fcgi?db=pubmed&retmode=json&id='; const request = url + item; let $row = $('#' + item); if (!$row.attr('aria-label')) { fetch(request, { method : 'GET', mode: 'cors', headers: {} }) .then((response) => response.json()) .then((response) => { setTimeout(() => { const res = response.result[item]; $(`a[id="${item}"]`).each(function () { $(this).attr( 'aria-label', `${res.title}\n\n${_.map(res.authors, (a) => a.name).join( ', ' )}` ); }); }, 0); }); } } }, createTable(id, data) { const vm = this; _.forEach(data, (d) => { d.DT_RowID = `${d.uniprot_id}`; }); const columns = vm.isExperimental ? [ { title: 'UniProt', data: 'uniprot_id', className: 'text-nowrap', fnCreatedCell: (nTd, sData, oData) => { $(nTd).html(`<a href="" class="protein-link"> ${sData} </a>`); }, }, { title: 'Gene Name', data: 'gene_name', fnCreatedCell: (nTd, sData, oData) => { if (sData) { $(nTd).html(`<a href="" class="protein-link"> ${sData}</a>`); } else { $(nTd).html(`<a href="" class="protein-link"> N/A</a>`); } }, }, { title: 'Name', data: 'name', fnCreatedCell: (nTd, sData, oData) => { if (sData) { $(nTd).html(`<a href="" class="protein-link"> ${sData}</a>`); } else { $(nTd).html( `<a href="" class="protein-link"> ${oData.uniprot_id}</a>` ); } }, }, // { // title: 'Name', // data: 'name', // fnCreatedCell: (nTd, sData, oData) => { // if (sData) { // $(nTd).html(`<a href="" class="protein-link"> ${sData}</a>`); // } else { // $(nTd).html( // `<a href="" class="protein-link"> ${oData.uniprot_id}</a>` // ); // } // }, // }, // { // title: 'Species', // data: 'species_name', // className: "text-nowrap" // }, // { // title: 'Evidences', // data: 'species_name', // className: "text-nowrap", // fnCreatedCell: (nTd, sData, oData) => { // // console.log(sData) // let data = vm.map[oData.uniprot_id]; // if(data) { // // $(nTd).html(data.filter(a => a.startsWith('http')).join('\n')); // $(nTd).html(data.map(i => vm.createLink(i)).join('<br/>')); // } else { // $(nTd).html('') // } // } // }, { title: 'Pubmed', data: 'uniprot_id', className: 'text-nowrap', render: function (data, type, row, meta) { if (vm.pubmed) { let dat = vm.pubmed[row.uniprot_id]; if (dat) { return dat.join(', '); } else { return ''; } } else { return ''; } }, fnCreatedCell: (nTd, sData, oData) => { // console.log(sData) if (vm.pubmed) { let data = vm.pubmed[oData.uniprot_id]; if (data) { // $(nTd).html(data.filter(a => a.startsWith('http')).join('\n')); // $(nTd).html(data.map(i => vm.createLink(i)).join('<br/>')); $(nTd).html( data.map((i) => vm.createPubMedLink(i)).join(' ') ); } else { $(nTd).html(''); } } else { $(nTd).html(''); } }, }, // { // title: 'Functional Type', // data: 'protein_functional_type', // className: 'whitespace-normal', // defaultContent: '<i>No data</i>', // render: function (data, type, row, meta) { // // console.log(_.flatMap(row.condensates, c => c.data_sources)) // if(!vm.proteinFunctionalType){ // return; // } // let dat = vm.proteinFunctionalType[row.uniprot_id]; // if (dat) { // return dat; // } else{ // return ''; // } // }, // }, // { // title: 'Experimental Evidence', // data: 'protein_exp_evidence', // className: 'whitespace-normal', // defaultContent: '<i>No data</i>', // render: function (data, type, row, meta) { // // console.log(_.flatMap(row.condensates, c => c.data_sources)) // if(!vm.proteinExperimentalEvidence){ // return; // } // let dat = vm.proteinExperimentalEvidence[row.uniprot_id]; // if (dat) { // return dat.join(', '); // } // return ''; // }, // }, // { // title: 'Driver Criterion', // data: 'driver_criterion', // className: 'whitespace-normal', // defaultContent: '<i>No data</i>', // render: function (data, type, row, meta) { // // console.log(_.flatMap(row.condensates, c => c.data_sources)) // if(!vm.proteinDriverCriterion){ // return // } // let dat = vm.proteinDriverCriterion[row.uniprot_id]; // if (dat) { // return dat.join(', '); // } // return ''; // }, // }, { title: 'DB', data: 'uniprot_id', className: 'text-nowrap', render: function (data, type, row, meta) { // console.log(_.flatMap(row.condensates, c => c.data_sources)) let dat = vm.dbTags[row.uniprot_id]; if (dat) { return dat.join(', '); } return ''; }, }, // { // title: 'Evidence', // data: 'uniprot_id', // className: "text-nowrap", // fnCreatedCell: (nTd, sData, oData) => { // $(nTd).html(`${vm.map[oData.uniprot_id]}`); // }, // }, // { // title: 'Sequence', // data: 'sequence', // className: "text-nowrap", // fnCreatedCell: (nTd, sData, oData) => { // $(nTd).html(`<input type="text" value="${sData}"> // <button class="copy-button" name="${oData.uniprot_id}" id="${oData.uniprot_id}" data-clipboard-text="${sData}"><i class="glyphicon glyphicon-copy"></i> </button>`); // }, // } { title: 'Confidence Score', className: 'text-nowrap', data: 'uniprot_id', render: function (data, type, row, meta) { // console.log(_.flatMap(row.condensates, c => c.data_sources)) let dat = vm.map[row.uniprot_id]; if (dat) { return dat; } return ''; }, fnCreatedCell: (nTd, sData, oData) => { // console.log(sData) let data = vm.map[oData.uniprot_id]; if (data) { $(nTd).html(getRating(data).join('\n')); } }, }, // { // title: 'Action', // data: 'uniprot_id', // className: 'text-nowrap', // fnCreatedCell: (nTd, sData, oData) => { // $(nTd).html( // `<button class="btn btn-primary edit-link btn-outline font-bold" style="font-weight:bold"> // <i class="fa fa-edit" style="font-weight:bold"></i> // </button> // <button class="btn btn-danger delete-link btn-outline font-bold" style="font-weight:bold"> // <i class="fa fa-trash" style="font-weight:bold"></i> // </button> // ` // ); // }, // // render: function (data, type, row, meta) { // // if (this.$store.getters["User/userRole"] === "Maintainer") { // // $(nTd).html( // // `<button class="btn btn-primary btn-outline font-bold" style="font-weight:bold">Edit // // <i class="fa ml-2 fa-edit" style="font-weight:bold"></i> // // </button>` // // ); // // } else { // // return ""; // // } // // }, // }, ] : [ { title: 'UniProt', data: 'uniprot_id', className: 'whitespace-normal', fnCreatedCell: (nTd, sData, oData) => { $(nTd).html(`<a href="" class="protein-link"> ${sData} </a>`); }, }, { title: 'Gene Name', data: 'gene_name', className: 'whitespace-normal', fnCreatedCell: (nTd, sData, oData) => { if (sData) { $(nTd).html(`<a href="" class="protein-link"> ${sData}</a>`); } else { $(nTd).html(`<a href="" class="protein-link"> N/A</a>`); } }, }, { title: 'Name', data: 'name', className: 'whitespace-normal break-all', fnCreatedCell: (nTd, sData, oData) => { if (sData) { $(nTd).html(`<a href="" class="protein-link"> ${sData}</a>`); } else { $(nTd).html( `<a href="" class="protein-link"> ${oData.uniprot_id}</a>` ); } }, }, // { // title: 'Evidences', // data: 'uniprot_id', // className: "text-nowrap", // fnCreatedCell: (nTd, sData, oData) => { // // console.log(sData) // let data = vm.map[oData.uniprot_id]; // // if(data) { // // $(nTd).html(data.filter(a => a.startsWith('http')).join('\n')); // $(nTd).html(data.map(i => vm.createLink(i)).join('<br/>')); // } else { // $(nTd).html('') // } // } // }, { title: 'Pubmed', data: 'uniprot_id', className: 'whitespace-normal', render: function (data, type, row, meta) { if (vm.pubmed) { let dat = vm.pubmed[row.uniprot_id]; if (dat) { return dat.join(', '); } else { return ''; } } else { return ''; } }, fnCreatedCell: (nTd, sData, oData) => { // console.log(sData) if (vm.pubmed) { let data = vm.pubmed[oData.uniprot_id]; if (data) { // $(nTd).html(data.filter(a => a.startsWith('http')).join('\n')); // $(nTd).html(data.map(i => vm.createLink(i)).join('<br/>')); $(nTd).html( data.map((i) => vm.createPubMedLink(i)).join(' ') ); } else { $(nTd).html(''); } } else { $(nTd).html(''); } }, }, { title: 'Functional Type', data: 'protein_functional_type', className: 'whitespace-nowrap', render: function (data, type, row, meta) { // console.log(_.flatMap(row.condensates, c => c.data_sources)) if (!vm.proteinFunctionalType) { return; } let dat = vm.proteinFunctionalType[row.uniprot_id]; if (dat) { return _.startCase(dat); } else { return ''; } }, }, { title: 'Experimental Evidence', data: 'protein_exp_evidence', className: 'whitespace-normal', render: function (data, type, row, meta) { // console.log(_.flatMap(row.condensates, c => c.data_sources)) if (!vm.proteinExperimentalEvidence) { return; } let dat = vm.proteinExperimentalEvidence[row.uniprot_id]; if (dat) { const val= dat.map(i=> i==='frap'? dat[i]=i.toUpperCase() : _.startCase(i)) return val.join(', '); } return ''; }, }, { title: 'Driver Criterion', data: 'driver_criterion', className: 'whitespace-normal', render: function (data, type, row, meta) { // console.log(_.flatMap(row.condensates, c => c.data_sources)) if (!vm.proteinDriverCriterion) { return; } let dat = vm.proteinDriverCriterion[row.uniprot_id]; if (dat) { const val= dat.map(i=> i==='self_ps'? dat[i]='Self-PS': _.startCase(i)) return val.join(', '); } return ''; }, }, { title: 'DB', data: 'uniprot_id', className: 'whitespace-normal', render: function (data, type, row, meta) { // console.log(_.flatMap(row.condensates, c => c.data_sources)) let dat = vm.dbTags[row.uniprot_id]; if (dat) { return dat.join(', '); } return ''; }, }, // { // title: 'Evidence', // data: 'uniprot_id', // className: "text-nowrap", // fnCreatedCell: (nTd, sData, oData) => { // $(nTd).html(`${vm.map[oData.uniprot_id]}`); // }, // }, // { // title: 'Sequence', // data: 'sequence', // className: "text-nowrap", // fnCreatedCell: (nTd, sData, oData) => { // $(nTd).html(`<input type="text" value="${sData}"> // <button class="copy-button" name="${oData.uniprot_id}" id="${oData.uniprot_id}" data-clipboard-text="${sData}"><i class="glyphicon glyphicon-copy"></i> </button>`); // }, // } { title: 'Confidence Score', className: 'whitespace-nowrap', data: 'uniprot_id', name: 'confidenceScore', render: function (data, type, row, meta) { // console.log(_.flatMap(row.condensates, c => c.data_sources)) let dat = vm.map[row.uniprot_id]; if (dat) { // console.log(getRatingValue(vm.map[row.uniprot_id])) return dat; } return ''; }, fnCreatedCell: (nTd, sData, oData) => { let data = vm.map[oData.uniprot_id]; if (data) { $(nTd).html(getRating(data).join('\n')); } }, }, { title: 'Action', data: 'uniprot_id', name: 'action', className: 'text-nowrap', fnCreatedCell: (nTd, sData, oData) => { $(nTd).html( `<button class="rounded-md bg-transparent hover:bg-blue-600 text-blue-700 hover:text-white border border-blue-500 hover:border-transparent focus:ring-2 focus:ring-blue-300 items-center px-4 py-2 text-center edit-link "> Edit </button> <button class="rounded-md bg-transparent hover:bg-red-600 text-red-700 hover:text-white border border-red-500 hover:border-transparent focus:ring-2 focus:ring-red-300 items-center px-4 py-2 font-bold text-center delete-link"> Remove </button> ` ); }, // render: function (data, type, row, meta) { // if (this.$store.getters["User/userRole"] === "Maintainer") { // $(nTd).html( // `<button class="btn btn-primary btn-outline font-bold" style="font-weight:bold">Edit // <i class="fa ml-2 fa-edit" style="font-weight:bold"></i> // </button>` // ); // } else { // return ""; // } // }, }, ]; const nTableOptions = { columns, // aaSorting: [[ 0, 'asc' ]], lengthMenu: [ [10, 25, 50, -1], [10, 25, 50, 'All'], ], paging: true, searching: true, info: false, data, order: [], // order: [[0, 'asc']], bDestroy: true, // Add this property to new setting, oLanguage: { sSearch: 'Filter', }, dom: '<"row"<"col-sm-2"l><"col-sm-2"f><"col-sm-6"p><"#download.col-sm-2">><"row"t><"row"<"col-sm-4"i><"col-sm-8"p>>', // initComplete: function () { // this.api().columns().every( function () { // var column = this; // var select = $('<select><option value=""></option></select>') // .appendTo( $(column.header()).empty() ) // .on( 'change', function () { // var val = $.fn.dataTable.util.escapeRegex( // $(this).val() // ); // column // .search( val ? '^'+val+'$' : '', true, false ) // .draw(); // } ); // column.data().unique().sort().each( function ( d, j ) { // select.append( '<option value="'+d+'">'+d+'</option>' ) // } ); // } ); // } }; const tableId = `#${id}`; if (table) { table.destroy(); $(tableId).empty(); } table = $(tableId).DataTable(nTableOptions); $('#download').html('<div style="text-align: right;"><div class="dropdown">\n' + ' <button class="btn btn-primary" type="button" id="dropdownMenuButton">\n' + ' Download CSV\n' + ' </button>\n' + '</div></div>'); if ( !this.$store.getters['User/userRole'] || this.$store.getters['User/userRole'] === 'Administrator' || this.$store.getters['User/userRole'] === 'Authenticated' ) { var colIndex; table.columns().every(function () { colIndex = table.column('action:name').index(); // ... do something with data(), or this.nodes(), etc }); table.column(colIndex).visible(false); } const tableBody = `${tableId} tbody`; $(tableBody).on('click', 'tr td a.protein-link', (e) => { e.preventDefault(); const tr = $(e.target).parent().parent(); const row = table.row(tr); vm.fetchProtein(row.data().uniprot_id); }); $(tableBody).on('click', 'tr td a.uniprot-link', (e) => { e.preventDefault(); const tr = $(e.target).parent().parent(); const row = table.row(tr); vm.forwardUniprot(row.data().uniprot_id); }); $(tableBody).on('click', 'tr td button.edit-link', (e) => { e.preventDefault(); const tr = $(e.target).parent().parent(); const row = table.row(tr); const id = row.data().uniprot_id; let findScore; for (let score in vm.map) { if (score === id) { findScore = vm.map[score]; } } let findProteinFunctionalType; for (let type in vm.proteinFunctionalType) { if (type === id) { findProteinFunctionalType = vm.proteinFunctionalType[type]; } } let proteinExpEvi; for (let exp in vm.proteinExperimentalEvidence) { if (exp === id) { proteinExpEvi = vm.proteinExperimentalEvidence[exp]; } } let proteinDriCri; for (let driverCri in vm.proteinDriverCriterion) { if (driverCri === id) { proteinDriCri = vm.proteinDriverCriterion[driverCri]; } } vm.proteinFunctionalTypeData = findProteinFunctionalType; vm.proteinExperimentalEvidenceData = proteinExpEvi; vm.proteinDriverCriterionData = proteinDriCri; vm.proteinConfidenceScore = findScore; vm.selectedRowData = row.data(); vm.uniprotId = id; vm.canonicaliD = vm.canonicalId; vm.toggleActionModal = true; // vm.$router.push(`/protein/editDetails/${id}`); // vm.fetchPubMedId(e.target.id); }); $(tableBody).on('click', 'tr td button.delete-link', (e) => { e.preventDefault(); const tr = $(e.target).parent().parent(); const row = table.row(tr); const id = row.data().uniprot_id; vm.uniprotId = id; vm.toggleDeleteModal = true; // vm.$router.push(`/protein/editDetails/${id}`); // vm.fetchPubMedId(e.target.id); }); $(tableBody).on('mouseover', 'tr td a.pubmed-link', (e) => { e.preventDefault(); // console.log(e.target.id) vm.fetchPubMedId(e.target.id); }); $('#download').on('click', (e) => { e.preventDefault(); vm.downloadCsv(); }); }, async downloadCsv() { const vm = this; if (vm.data) { console.log(vm.data) const data = vm.data; let exports = []; let header = ['UniProt', 'Gene Name', 'Name', 'Pubmed', 'Functional Type', 'Experimental Evidence', 'Driver Criterion', 'DB', 'Confidence Score']; exports.push(header.join(', ')); _.forEach(data, item => { let pubMedIds = []; if (vm.pubmed) { let pubMedId = vm.pubmed[item.uniprot_id]; if (pubMedId) { _.each(item.pubmed_ids, (i) => { pubMedIds.push(`${i}`); }); } } const id = item.uniprot_id; let findScore; for (let score in vm.map) { if (score === id) { findScore = vm.map[score]; } } let findProteinFunctionalType; for (let type in vm.proteinFunctionalType) { if (type === id) { findProteinFunctionalType = vm.proteinFunctionalType[type]; } } let proteinExpEvi; for (let exp in vm.proteinExperimentalEvidence) { if (exp === id) { proteinExpEvi = vm.proteinExperimentalEvidence[exp]; } } let proteinDriCri; for (let driverCri in vm.proteinDriverCriterion) { if (driverCri === id) { proteinDriCri = vm.proteinDriverCriterion[driverCri]; } } let dbTags; if (vm.dbTags) { let dat = vm.dbTags[id]; dbTags = dat.join('\t'); } exports.push([`"${item.uniprot_id}"`, `"${item.gene_name}"`, `"${item.name}"`, `"${pubMedIds.join('\t')}"`, findProteinFunctionalType, proteinExpEvi, proteinDriCri, dbTags, findScore].join(',')); }) let blob = new Blob([exports.join('\n')], {type: 'text/csv'}) let contentDisposition = 'Content-Disposition: attachment; filename="download-data.csv"' let filename = contentDisposition.split('filename=')[1] filename = filename.replace(/"/g, '') let link = vm.$refs.download link.href = window.URL.createObjectURL(blob) link.download = filename link.click() } }, }, }; </script> <style> table.dataTable.row-border > tbody > tr:first-child > th, table.dataTable.row-border > tbody > tr:first-child > td, table.dataTable.display > tbody > tr:first-child > th, table.dataTable.display > tbody > tr:first-child > td { border-top: none; } table.dataTable.row-border > tbody > tr > th, table.dataTable.row-border > tbody > tr > td, table.dataTable.display > tbody > tr > th, table.dataTable.display > tbody > tr > td { border-top: 1px solid #ddd; } table.dataTable > tbody > tr { background-color: #ffffff; } table.dataTable.row-border > tbody > tr:hover, table.dataTable.display > tbody > tr:hover { background-color: #f6f6f6; } select.form-control { font-size: 12px; padding: 3px 12px; } ul.pagination { font-size: 1rem; } .form-inline .form-control { height: 25px; line-height: 25px; vertical-align: middle; } .protein-link { font-weight: bold; color: #0065b9; } .uniprot-link { font-weight: bold; color: #0065b9; } .pubmed-link { font-weight: bold; color: #0065b9; } .external-link { font-weight: bold; color: #0065b9; } .pagination { font-size: 1.2rem; } </style>