protvista-uniprot 2.12.2 → 2.13.0

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.
Files changed (58) hide show
  1. package/README.md +2 -2
  2. package/dist/es/commonTypes.d.ts +1 -1
  3. package/dist/es/config.json +94 -67
  4. package/dist/es/filterConfig.d.ts +4 -3
  5. package/dist/es/filterConfig.js +48 -32
  6. package/dist/es/filterConfig.js.map +1 -1
  7. package/dist/es/index.d.ts +0 -2
  8. package/dist/es/index.js +0 -3
  9. package/dist/es/index.js.map +1 -1
  10. package/dist/es/protvista-alphafold-confidence.d.ts +1 -1
  11. package/dist/es/protvista-alphamissense-heatmap.d.ts +8 -0
  12. package/dist/es/protvista-alphamissense-heatmap.js +35 -0
  13. package/dist/es/protvista-alphamissense-heatmap.js.map +1 -0
  14. package/dist/es/protvista-alphamissense-pathogenicity.d.ts +3 -1
  15. package/dist/es/protvista-alphamissense-pathogenicity.js +2 -2
  16. package/dist/es/protvista-alphamissense-pathogenicity.js.map +1 -1
  17. package/dist/es/protvista-ptm-exchange.d.ts +7 -7
  18. package/dist/es/protvista-ptm-exchange.js +6 -4
  19. package/dist/es/protvista-ptm-exchange.js.map +1 -1
  20. package/dist/es/protvista-uniprot-structure.d.ts +6 -1
  21. package/dist/es/protvista-uniprot-structure.js +137 -66
  22. package/dist/es/protvista-uniprot-structure.js.map +1 -1
  23. package/dist/es/protvista-uniprot.d.ts +27 -16
  24. package/dist/es/protvista-uniprot.js +166 -145
  25. package/dist/es/protvista-uniprot.js.map +1 -1
  26. package/dist/es/protvista-variation-graph-adapter.d.ts +9 -0
  27. package/dist/es/protvista-variation-graph-adapter.js +46 -0
  28. package/dist/es/protvista-variation-graph-adapter.js.map +1 -0
  29. package/dist/es/styles/protvista-styles.js +8 -13
  30. package/dist/es/styles/protvista-styles.js.map +1 -1
  31. package/dist/protvista-uniprot.js +217 -217
  32. package/dist/protvista-uniprot.js.LICENSE.txt +24 -57
  33. package/dist/protvista-uniprot.js.map +1 -1
  34. package/package.json +15 -16
  35. package/src/config.json +94 -67
  36. package/src/filterConfig.ts +58 -55
  37. package/src/index.ts +0 -3
  38. package/src/protvista-alphamissense-heatmap.ts +52 -0
  39. package/src/protvista-alphamissense-pathogenicity.ts +2 -2
  40. package/src/protvista-ptm-exchange.ts +21 -19
  41. package/src/protvista-uniprot-structure.ts +168 -94
  42. package/src/protvista-uniprot.ts +226 -168
  43. package/src/protvista-variation-graph-adapter.ts +47 -0
  44. package/src/styles/protvista-styles.ts +8 -13
  45. package/src/types/nightingale-components.d.ts +1 -1
  46. package/src/types/nightingale-sequence-heatmap.d.ts +1 -0
  47. package/dist/es/download-panel.d.ts +0 -29
  48. package/dist/es/download-panel.js +0 -137
  49. package/dist/es/download-panel.js.map +0 -1
  50. package/src/download-panel.ts +0 -164
  51. package/src/types/protvista-filter.d.ts +0 -16
  52. package/src/types/protvista-interpro-track.d.ts +0 -1
  53. package/src/types/protvista-manager.d.ts +0 -1
  54. package/src/types/protvista-navigation.d.ts +0 -1
  55. package/src/types/protvista-sequence.d.ts +0 -1
  56. package/src/types/protvista-tooltip.d.ts +0 -8
  57. package/src/types/protvista-track.d.ts +0 -5
  58. package/src/types/protvista-variation-graph.d.ts +0 -1
@@ -33,6 +33,35 @@ export const getFilteredVariants = (
33
33
  };
34
34
  });
35
35
 
36
+ const filterPredicates = {
37
+ disease: (variantPos) =>
38
+ variantPos.association?.some((association) => association.disease),
39
+ predicted: (variantPos) => variantPos.hasPredictions,
40
+ nonDisease: (variantPos) =>
41
+ variantPos.association?.some(
42
+ (association) => association.disease === false
43
+ ),
44
+ uncertain: (variantPos) =>
45
+ (typeof variantPos.clinicalSignificances === 'undefined' &&
46
+ !variantPos.hasPredictions) ||
47
+ (variantPos.clinicalSignificances &&
48
+ significanceMatches(
49
+ variantPos.clinicalSignificances,
50
+ consequences.uncertain
51
+ )),
52
+ UniProt: (variantPos) =>
53
+ variantPos.xrefNames &&
54
+ (variantPos.xrefNames.includes('uniprot') ||
55
+ variantPos.xrefNames.includes('UniProt')),
56
+ ClinVar: (variantPos) =>
57
+ variantPos.xrefNames &&
58
+ (variantPos.xrefNames.includes('ClinVar') ||
59
+ variantPos.xrefNames.includes('clinvar')),
60
+ LSS: (variantPos) =>
61
+ variantPos.sourceType === 'large_scale_study' ||
62
+ variantPos.sourceType === 'mixed',
63
+ };
64
+
36
65
  const filterConfig = [
37
66
  {
38
67
  name: 'disease',
@@ -41,13 +70,12 @@ const filterConfig = [
41
70
  text: 'Filter Consequence',
42
71
  },
43
72
  options: {
44
- labels: ['Likely pathogenic or pathogenic'],
45
- colors: [scaleColors.UPDiseaseColor],
73
+ label: 'Likely pathogenic or pathogenic',
74
+ color: scaleColors.UPDiseaseColor,
46
75
  },
76
+ filterPredicate: filterPredicates['disease'],
47
77
  filterData: (variants: ProtvistaVariationData) =>
48
- getFilteredVariants(variants, (variantPos) =>
49
- variantPos.association?.some((association) => association.disease)
50
- ),
78
+ getFilteredVariants(variants, filterPredicates['disease']),
51
79
  },
52
80
  {
53
81
  name: 'predicted',
@@ -56,11 +84,12 @@ const filterConfig = [
56
84
  text: 'Filter Consequence',
57
85
  },
58
86
  options: {
59
- labels: ['Predicted consequence'],
60
- colors: [scaleColors.predictedColor],
87
+ label: 'Predicted consequence',
88
+ color: scaleColors.predictedColor,
61
89
  },
90
+ filterPredicate: filterPredicates['predicted'],
62
91
  filterData: (variants: ProtvistaVariationData) =>
63
- getFilteredVariants(variants, (variantPos) => variantPos.hasPredictions),
92
+ getFilteredVariants(variants, filterPredicates['predicted']),
64
93
  },
65
94
  {
66
95
  name: 'nonDisease',
@@ -69,15 +98,12 @@ const filterConfig = [
69
98
  text: 'Filter Consequence',
70
99
  },
71
100
  options: {
72
- labels: ['Likely benign or benign'],
73
- colors: [scaleColors.UPNonDiseaseColor],
101
+ label: 'Likely benign or benign',
102
+ color: scaleColors.UPNonDiseaseColor,
74
103
  },
104
+ filterPredicate: filterPredicates['nonDisease'],
75
105
  filterData: (variants: ProtvistaVariationData) =>
76
- getFilteredVariants(variants, (variantPos) =>
77
- variantPos.association?.some(
78
- (association) => association.disease === false
79
- )
80
- ),
106
+ getFilteredVariants(variants, filterPredicates['nonDisease']),
81
107
  },
82
108
  {
83
109
  name: 'uncertain',
@@ -86,21 +112,12 @@ const filterConfig = [
86
112
  text: 'Filter Consequence',
87
113
  },
88
114
  options: {
89
- labels: ['Uncertain significance'],
90
- colors: [scaleColors.othersColor],
115
+ label: 'Uncertain significance',
116
+ color: scaleColors.othersColor,
91
117
  },
118
+ filterPredicate: filterPredicates['uncertain'],
92
119
  filterData: (variants: ProtvistaVariationData) =>
93
- getFilteredVariants(
94
- variants,
95
- (variantPos) =>
96
- (typeof variantPos.clinicalSignificances === 'undefined' &&
97
- !variantPos.hasPredictions) ||
98
- (variantPos.clinicalSignificances &&
99
- significanceMatches(
100
- variantPos.clinicalSignificances,
101
- consequences.uncertain
102
- ))
103
- ),
120
+ getFilteredVariants(variants, filterPredicates['uncertain']),
104
121
  },
105
122
  {
106
123
  name: 'UniProt',
@@ -109,17 +126,12 @@ const filterConfig = [
109
126
  text: 'Filter Provenance',
110
127
  },
111
128
  options: {
112
- labels: ['UniProt reviewed'],
113
- colors: ['#9f9f9f'],
129
+ label: 'UniProt reviewed',
130
+ color: '#9f9f9f',
114
131
  },
132
+ filterPredicate: filterPredicates['UniProt'],
115
133
  filterData: (variants: ProtvistaVariationData) =>
116
- getFilteredVariants(
117
- variants,
118
- (variantPos) =>
119
- variantPos.xrefNames &&
120
- (variantPos.xrefNames.includes('uniprot') ||
121
- variantPos.xrefNames.includes('UniProt'))
122
- ),
134
+ getFilteredVariants(variants, filterPredicates['UniProt']),
123
135
  },
124
136
  {
125
137
  name: 'ClinVar',
@@ -128,17 +140,12 @@ const filterConfig = [
128
140
  text: 'Filter Provenance',
129
141
  },
130
142
  options: {
131
- labels: ['ClinVar'],
132
- colors: ['#9f9f9f'],
143
+ label: 'ClinVar',
144
+ color: '#9f9f9f',
133
145
  },
146
+ filterPredicate: filterPredicates['ClinVar'],
134
147
  filterData: (variants: ProtvistaVariationData) =>
135
- getFilteredVariants(
136
- variants,
137
- (variantPos) =>
138
- variantPos.xrefNames &&
139
- (variantPos.xrefNames.includes('ClinVar') ||
140
- variantPos.xrefNames.includes('clinvar'))
141
- ),
148
+ getFilteredVariants(variants, filterPredicates['ClinVar']),
142
149
  },
143
150
  {
144
151
  name: 'LSS',
@@ -147,16 +154,12 @@ const filterConfig = [
147
154
  text: 'Filter Provenance',
148
155
  },
149
156
  options: {
150
- labels: ['Large scale studies'],
151
- colors: ['#9f9f9f'],
157
+ label: 'Large scale studies',
158
+ color: '#9f9f9f',
152
159
  },
160
+ filterPredicate: filterPredicates['LSS'],
153
161
  filterData: (variants: ProtvistaVariationData) =>
154
- getFilteredVariants(
155
- variants,
156
- (variantPos) =>
157
- variantPos.sourceType === 'large_scale_study' ||
158
- variantPos.sourceType === 'mixed'
159
- ),
162
+ getFilteredVariants(variants, filterPredicates['LSS']),
160
163
  },
161
164
  ];
162
165
 
@@ -172,7 +175,7 @@ const countVariantsForFilter = (
172
175
  return false;
173
176
  };
174
177
 
175
- export const colorConfig = (variant: ProtvistaVariant) => {
178
+ export const colorConfig = (variant: any) => {
176
179
  if (countVariantsForFilter('disease', variant)) {
177
180
  return scaleColors.UPDiseaseColor;
178
181
  } else if (countVariantsForFilter('nonDisease', variant)) {
package/src/index.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import { loadComponent } from './loadComponents';
2
2
 
3
3
  import ProtvistaUniprot from './protvista-uniprot';
4
- import _DownloadPanel from './download-panel';
5
4
  import _ProtvistaUniprotStructure from './protvista-uniprot-structure';
6
5
 
7
6
  import { transformDataFeatureAdapter as _transformDataFeatureAdapter } from './protvista-uniprot';
@@ -16,10 +15,8 @@ export const transformDataStructureAdapter = _transformDataStructureAdapter;
16
15
  export const transformDataVariationAdapter = _transformDataVariationAdapter;
17
16
  export const transformDataInterproAdapter = _transformDataInterproAdapter;
18
17
  export const ProtvistaUniprotStructure = _ProtvistaUniprotStructure;
19
- export const DownloadPanel = _DownloadPanel;
20
18
 
21
19
  loadComponent('protvista-uniprot', ProtvistaUniprot);
22
- loadComponent('download-panel', _DownloadPanel);
23
20
  loadComponent('protvista-uniprot-structure', _ProtvistaUniprotStructure);
24
21
 
25
22
  export default ProtvistaUniprot;
@@ -0,0 +1,52 @@
1
+ import {
2
+ cellSplitter,
3
+ rowSplitter,
4
+ } from './protvista-alphamissense-pathogenicity';
5
+ import { AlphafoldPayload } from './commonTypes';
6
+
7
+ const parseCSV = (rawText: string): Array<Record<string, string>> => {
8
+ const data = [];
9
+
10
+ for (const [i, row] of rawText.split(rowSplitter).entries()) {
11
+ if (i === 0 || !row) {
12
+ continue;
13
+ }
14
+ const [, , positionString, mutated, pathogenicityScore] =
15
+ row.match(cellSplitter);
16
+
17
+ data.push({
18
+ xValue: +positionString,
19
+ yValue: mutated,
20
+ score: +pathogenicityScore,
21
+ });
22
+ }
23
+ return data;
24
+ };
25
+
26
+ // Load and parse
27
+ const loadAndParseAnnotations = async (url: string): Promise<Array<Record<string, string>>> => {
28
+ try {
29
+ const payload = await fetch(url);
30
+ const rawCSV = await payload.text();
31
+ return parseCSV(rawCSV);
32
+ } catch (e) {
33
+ console.error('Could not load AlphaMissense pathogenicity', e);
34
+ }
35
+ };
36
+
37
+ type PartialProtein = {
38
+ sequence: {
39
+ sequence: string;
40
+ };
41
+ };
42
+
43
+ export const transformData = async (
44
+ data: AlphafoldPayload,
45
+ protein: PartialProtein
46
+ ) => {
47
+ const { amAnnotationsUrl, uniprotSequence } = data?.[0] || {};
48
+ if (amAnnotationsUrl && uniprotSequence === protein.sequence.sequence) {
49
+ const heatmapData = await loadAndParseAnnotations(amAnnotationsUrl);
50
+ return heatmapData;
51
+ }
52
+ };
@@ -7,8 +7,8 @@ import { AlphafoldPayload } from './commonTypes';
7
7
  const benign = 0.34;
8
8
  const pathogenic = 0.564;
9
9
 
10
- const rowSplitter = /\s*\n\s*/;
11
- const cellSplitter = /^(.)(\d+)(.),(.+),(\w+)$/;
10
+ export const rowSplitter = /\s*\n\s*/;
11
+ export const cellSplitter = /^(.)(\d+)(.),(.+),(\w+)$/;
12
12
 
13
13
  type Row = {
14
14
  wildType: string;
@@ -91,9 +91,7 @@ const convertPtmExchangePtms = (
91
91
  console.log('PTM has no confidence score');
92
92
  } else if (confidenceScores.size > 1) {
93
93
  console.error(
94
- `PTM has a mixture of confidence scores: ${Array.from(
95
- confidenceScores
96
- )}`
94
+ `PTM has a mixture of confidence scores: ${Array.from(confidenceScores)}`
97
95
  );
98
96
  } else {
99
97
  [confidenceScore] = confidenceScores;
@@ -101,22 +99,26 @@ const convertPtmExchangePtms = (
101
99
 
102
100
  const tooltip = `
103
101
  <h5>Description</h5><p>${phosphorylate(aa)}</p>
104
- ${confidenceScore ? `<h5 data-article-id="mod_res_large_scale#confidence-score">Confidence Score</h5><p>${confidenceScore}</p>` : ''}
102
+ ${
103
+ confidenceScore
104
+ ? `<h5 data-article-id="mod_res_large_scale#confidence-score">Confidence Score</h5><p>${confidenceScore}</p>`
105
+ : ''
106
+ }
105
107
  ${
106
108
  evidences
107
109
  ? `<h5>Evidence</h5><ul>${evidences
108
- .map(
109
- (id) => {
110
- const datasetID = id === 'Glue project' ? 'PXD012174' : id;
111
- return `<li title='${datasetID}' style="padding: .25rem 0">${datasetID}&nbsp;
112
- (<a href="https://www.ebi.ac.uk/pride/archive/projects/${id}" style="color:#FFF" target="_blank">PRIDE</a>)
110
+ .map((id) => {
111
+ const datasetID = id === 'Glue project' ? 'PXD012174' : id;
112
+ return `<li title='${datasetID}' style="padding: .25rem 0">${datasetID}&nbsp;
113
+ (<a href="https://proteomecentral.proteomexchange.org/dataset/${datasetID}" style="color:#FFF" target="_blank">ProteomeXchange</a>)
113
114
  </li>
114
- ${id === 'Glue project' ?
115
- `<li title="publication" style="padding: .25rem 0">Publication:&nbsp;31819260&nbsp;(<a href="https://pubmed.ncbi.nlm.nih.gov/31819260" style="color:#FFF" target="_blank">PubMed</a>)</li>`
116
- : ''}
117
- `
118
- }
119
- )
115
+ ${
116
+ id === 'Glue project'
117
+ ? `<li title="publication" style="padding: .25rem 0">Publication:&nbsp;31819260&nbsp;(<a href="https://pubmed.ncbi.nlm.nih.gov/31819260" style="color:#FFF" target="_blank">PubMed</a>)</li>`
118
+ : ''
119
+ }
120
+ `;
121
+ })
120
122
  .join('')}</ul>`
121
123
  : ''
122
124
  }
@@ -139,7 +141,7 @@ export const transformData = (data: ProteomicsPtm) => {
139
141
 
140
142
  const absolutePositionToPtms: Record<number, { ptms: PTM[]; aa: string }> =
141
143
  {};
142
-
144
+
143
145
  if (features) {
144
146
  for (const feature of features) {
145
147
  for (const ptm of feature.ptms) {
@@ -167,12 +169,12 @@ export const transformData = (data: ProteomicsPtm) => {
167
169
  }
168
170
  }
169
171
  }
170
-
172
+
171
173
  return Object.entries(absolutePositionToPtms).map(
172
174
  ([absolutePosition, { ptms, aa }]) =>
173
175
  convertPtmExchangePtms(ptms, aa, +absolutePosition)
174
176
  );
175
- }
177
+ }
176
178
  }
177
- return [];
179
+ return [];
178
180
  };
@@ -1,7 +1,10 @@
1
1
  import { LitElement, html, svg, TemplateResult, css } from 'lit-element';
2
2
  import { unsafeHTML } from 'lit-html/directives/unsafe-html.js';
3
3
  import { load } from 'data-loader';
4
- import ProtvistaStructure from 'protvista-structure';
4
+ import NightingaleStructure, {
5
+ PredictionData,
6
+ StructureData,
7
+ } from '@nightingale-elements/nightingale-structure';
5
8
  import ProtvistaDatatable from 'protvista-datatable';
6
9
  import { loadComponent } from './loadComponents';
7
10
 
@@ -9,11 +12,6 @@ import loaderIcon from './icons/spinner.svg';
9
12
  import downloadIcon from './icons/download.svg';
10
13
  import loaderStyles from './styles/loader-styles';
11
14
 
12
- import {
13
- PredictionData,
14
- StructureData,
15
- } from 'protvista-structure/dist/es/protvista-structure';
16
-
17
15
  const PDBLinks = [
18
16
  { name: 'PDBe', link: 'https://www.ebi.ac.uk/pdbe-srv/view/entry/' },
19
17
  { name: 'RCSB-PDB', link: 'https://www.rcsb.org/structure/' },
@@ -110,8 +108,35 @@ const AFMetaInfo = html`
110
108
  </p>
111
109
  `;
112
110
 
111
+ const AMMetaInfo = html`<strong>Model Pathogenicity:</strong>
112
+ <ul class="no-bullet">
113
+ <li>
114
+ <span class="af-legend" style="background-color: rgb(154, 19, 26)"></span>
115
+ Likely pathogenic (score > 0.564)
116
+ </li>
117
+ <li>
118
+ <span
119
+ class="af-legend"
120
+ style="background-color: rgb(168, 169, 173)"
121
+ ></span>
122
+ Uncertain (0.564 >= score >= 0.34)
123
+ </li>
124
+ <li>
125
+ <span class="af-legend" style="background-color: rgb(61, 84, 147)"></span>
126
+ Likely benign (score < 0.34)
127
+ </li>
128
+ </ul>
129
+ <p class="small">
130
+ The displayed colour for each residue is the average AlphaMissense
131
+ pathogenicity score across all possible amino acid substitutions at that
132
+ position.
133
+ </p>`;
134
+
113
135
  const foldseekURL = (accession, sourceDB) => {
114
- return html`<a href="${foldseekLink}?accession=${accession}&source=${sourceDB}">Foldseek</a>`;
136
+ return html`<a
137
+ href="${foldseekLink}?accession=${accession}&source=${sourceDB}"
138
+ >Foldseek</a
139
+ >`;
115
140
  };
116
141
 
117
142
  const styleId = 'protvista-styles';
@@ -120,15 +145,17 @@ class ProtvistaUniprotStructure extends LitElement {
120
145
  data?: ProcessedStructureData[];
121
146
  structureId?: string;
122
147
  metaInfo?: TemplateResult;
148
+ colorTheme?: string;
123
149
  private loading?: boolean;
124
150
 
125
151
  constructor() {
126
152
  super();
127
- loadComponent('protvista-structure', ProtvistaStructure);
153
+ loadComponent('nightingale-structure', NightingaleStructure);
128
154
  loadComponent('protvista-datatable', ProtvistaDatatable);
129
155
  this.loading = true;
130
156
  this.onTableRowClick = this.onTableRowClick.bind(this);
131
157
  this.addStyles();
158
+ this.colorTheme = 'alphafold';
132
159
  }
133
160
 
134
161
  static get properties() {
@@ -137,6 +164,7 @@ class ProtvistaUniprotStructure extends LitElement {
137
164
  structureId: { type: String },
138
165
  data: { type: Object },
139
166
  loading: { type: Boolean },
167
+ colorTheme: { type: String },
140
168
  };
141
169
  }
142
170
 
@@ -219,6 +247,12 @@ class ProtvistaUniprotStructure extends LitElement {
219
247
 
220
248
  get cssStyle() {
221
249
  return css`
250
+ .protvista-uniprot-structure {
251
+ line-height: normal;
252
+ }
253
+ .theme-selection {
254
+ padding-bottom: 1rem;
255
+ }
222
256
  .protvista-uniprot-structure__structure {
223
257
  display: flex;
224
258
  }
@@ -226,7 +260,7 @@ class ProtvistaUniprotStructure extends LitElement {
226
260
  flex: 1;
227
261
  padding: 1rem;
228
262
  }
229
- .protvista-uniprot-structure__structure protvista-structure {
263
+ .protvista-uniprot-structure__structure nightingale-structure {
230
264
  z-index: 40000;
231
265
  width: 100%;
232
266
  flex: 4;
@@ -263,102 +297,142 @@ class ProtvistaUniprotStructure extends LitElement {
263
297
  return this;
264
298
  }
265
299
 
300
+ toggleColorTheme(e) {
301
+ this.colorTheme = e.target.value;
302
+ if (e.target.value === 'alphafold') {
303
+ this.metaInfo = AFMetaInfo;
304
+ } else {
305
+ this.metaInfo = AMMetaInfo;
306
+ }
307
+ }
308
+
266
309
  render() {
267
310
  return html`
268
311
  <div class="protvista-uniprot-structure">
269
312
  <div class="protvista-uniprot-structure__structure">
270
313
  ${this.metaInfo
271
- ? html`<div class="protvista-uniprot-structure__meta">
314
+ ? html` <div class="protvista-uniprot-structure__meta">
315
+ <div class="theme-selection">
316
+ Select color scale <br />
317
+ <input
318
+ type="radio"
319
+ id="alphafold"
320
+ name="colorScheme"
321
+ value="alphafold"
322
+ @click=${(e) => this.toggleColorTheme(e)}
323
+ checked
324
+ />
325
+ <label for="alphafold">Confidence</label><br />
326
+ <input
327
+ type="radio"
328
+ id="alphamissense"
329
+ name="colorScheme"
330
+ value="alphamissense"
331
+ @click=${(e) => this.toggleColorTheme(e)}
332
+ />
333
+ <label for="alphamissense">Pathogenecity</label><br />
334
+ </div>
272
335
  ${this.metaInfo}
273
336
  </div>`
274
337
  : html``}
275
338
  ${this.structureId
276
- ? html`<protvista-structure
277
- structureid=${this.structureId}
278
- accession=${this.accession}
279
- ></protvista-structure>`
339
+ ? html`<nightingale-structure
340
+ structure-id=${this.structureId}
341
+ protein-accession=${this.accession}
342
+ color-theme=${this.colorTheme}
343
+ ></nightingale-structure>`
344
+ : html``}
345
+ </div>
346
+ <div class="protvista-uniprot-structure__table">
347
+ ${this.data && this.data.length
348
+ ? html`<protvista-datatable noScrollToRow noDeselect filter-scroll>
349
+ <table>
350
+ <thead>
351
+ <tr>
352
+ <th data-filter="source">Source</th>
353
+ <th>Identifier</th>
354
+ <th data-filter="method">Method</th>
355
+ <th>Resolution</th>
356
+ <th>Chain</th>
357
+ <th>Positions</th>
358
+ <th>Links</th>
359
+ <th><!--Download--></th>
360
+ </tr>
361
+ </thead>
362
+ <tbody>
363
+ ${this.data?.map(
364
+ ({
365
+ source,
366
+ id,
367
+ method,
368
+ resolution,
369
+ chain,
370
+ positions,
371
+ downloadLink,
372
+ }) => html`<tr
373
+ data-id="${id}"
374
+ @click="${() => this.onTableRowClick({ id })}"
375
+ >
376
+ <td data-filter="source" data-filter-value="${source}">
377
+ <strong>${source}</strong>
378
+ </td>
379
+ <td>${id}</td>
380
+ <td data-filter="method" data-filter-value="${method}">
381
+ ${method}
382
+ </td>
383
+ <td>
384
+ ${resolution ? resolution.replace('A', 'Å') : ''}
385
+ </td>
386
+ <td>${chain || ''}</td>
387
+ <td>${positions || ''}</td>
388
+ <td>
389
+ ${source === 'PDB'
390
+ ? html`
391
+ ${PDBLinks.map((pdbLink) => {
392
+ return html`
393
+ <a href="${pdbLink.link}${id}"
394
+ >${pdbLink.name}</a
395
+ >
396
+ `;
397
+ }).reduce(
398
+ (prev, curr) => html` ${prev} · ${curr} `
399
+ )}
400
+ `
401
+ : html`<a href="${alphaFoldLink}${this.accession}"
402
+ >AlphaFold</a
403
+ >`}
404
+ </td>
405
+ <td>
406
+ ${downloadLink
407
+ ? html`<a
408
+ href="${downloadLink}"
409
+ class="download-link"
410
+ >${svg`${unsafeHTML(downloadIcon)}`}</a
411
+ >
412
+ ·
413
+ ${foldseekURL(
414
+ source === 'PDB' ? id : this.accession,
415
+ source === 'PDB' ? 'PDB' : 'AlphaFoldDB'
416
+ )}`
417
+ : ''}
418
+ </td>
419
+ </tr>`
420
+ )}
421
+ </tbody>
422
+ </table>
423
+ </protvista-datatable>`
424
+ : html``}
425
+ ${this.loading
426
+ ? html`<div class="protvista-loader">
427
+ ${svg`${unsafeHTML(loaderIcon)}`}
428
+ </div>`
429
+ : html``}
430
+ ${!this.data && !this.loading
431
+ ? html`<div class="protvista-no-results">
432
+ No structure information available for ${this.accession}
433
+ </div>`
280
434
  : html``}
281
435
  </div>
282
- <div class="class="protvista-uniprot-structure__table">
283
- ${this.data && this.data.length
284
- ? html`<protvista-datatable noScrollToRow noDeselect filter-scroll>
285
- <table>
286
- <thead>
287
- <tr>
288
- <th data-filter="source">Source</th>
289
- <th>Identifier</th>
290
- <th data-filter="method">Method</th>
291
- <th>Resolution</th>
292
- <th>Chain</th>
293
- <th>Positions</th>
294
- <th>Links</th>
295
- <th><!--Download--></th>
296
- </tr>
297
- </thead>
298
- <tbody>
299
- ${this.data?.map(
300
- ({
301
- source,
302
- id,
303
- method,
304
- resolution,
305
- chain,
306
- positions,
307
- downloadLink,
308
- }) => html`<tr
309
- data-id="${id}"
310
- @click="${() => this.onTableRowClick({ id })}"
311
- >
312
- <td data-filter="source" data-filter-value="${source}">
313
- <strong>${source}</strong>
314
- </td>
315
- <td>${id}</td>
316
- <td data-filter="method" data-filter-value="${method}">
317
- ${method}
318
- </td>
319
- <td>${resolution ? resolution.replace('A', 'Å') : ''}</td>
320
- <td>${chain || ''}</td>
321
- <td>${positions || ''}</td>
322
- <td>
323
- ${source === 'PDB'
324
- ? html`
325
- ${PDBLinks.map((pdbLink) => {
326
- return html`
327
- <a href="${pdbLink.link}${id}"
328
- >${pdbLink.name}</a
329
- >
330
- `;
331
- }).reduce(
332
- (prev, curr) => html` ${prev} · ${curr} `
333
- )}
334
- `
335
- : html`<a href="${alphaFoldLink}${this.accession}"
336
- >AlphaFold</a
337
- >`}
338
- </td>
339
- <td>
340
- ${downloadLink
341
- ? html`<a href="${downloadLink}" class="download-link"
342
- >${svg`${unsafeHTML(downloadIcon)}`}</a
343
- > · ${foldseekURL(source === 'PDB' ? id: this.accession, source === 'PDB' ? 'PDB' : 'AlphaFoldDB')}`
344
- : ''}
345
- </td>
346
- </tr>`
347
- )}
348
- </tbody>
349
- </table>
350
- </protvista-datatable>`
351
- : html``}
352
- ${this.loading
353
- ? html`<div class="protvista-loader">
354
- ${svg`${unsafeHTML(loaderIcon)}`}
355
- </div>`
356
- : html``}
357
- ${!this.data && !this.loading
358
- ? html`<div class="protvista-no-results">
359
- No structure information available for ${this.accession}
360
- </div>`
361
- : html``}
362
436
  </div>
363
437
  `;
364
438
  }